[Skiboot] [RFC PATCH 10/10] keystore: add experimental opal_lock_variables runtime service
Eric Richter
erichte at linux.ibm.com
Thu Aug 2 08:53:49 AEST 2018
The opal_lock_variables runtime service can be called to lock specific
operations until the next full reboot. For example, it could be called
to write lock the keystore in-memory copy until the next full reboot.
Currently, only opal_set_variable and opal_secboot_commit are able to
write-locked.
NOTE: This is a very drafty patch. It is currently unknown if this
feature is even necessary, or if it even protects anything. The intended
use is to lock down the in-memory keystore after the update queue has
been processed in early skiroot, so that subsequent kernels can no
longer manipulate the in-memory keystore or secboot partition beyond
writes to the update queue.
Signed-off-by: Eric Richter <erichte at linux.ibm.com>
---
libstb/keystore.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/libstb/keystore.c b/libstb/keystore.c
index 1c853380..34e5b72e 100644
--- a/libstb/keystore.c
+++ b/libstb/keystore.c
@@ -30,6 +30,7 @@ static struct list_head active_bank_list = LIST_HEAD_INIT(active_bank_list);
static struct list_head update_queue_list = LIST_HEAD_INIT(update_queue_list);
static bool keystore_ready = false; /* has the keystore been loaded? */
+static int active_lock = 0;
// TODO: OPAL_UNSUPPORTED?
#define CHECK_KEYSTORE_READY if(!keystore_ready) {prlog(PR_ERR, "Ignoring call, keystore not ready\n"); return OPAL_RESOURCE; }
@@ -100,6 +101,11 @@ static int64_t opal_set_variable(uint64_t k_varname, uint64_t k_vardata, uint64_
bank = GET_BANK(section);
+ if ((section == ACTIVE_BANK) && (active_lock)) {
+ prlog(PR_ERR, "Variable Bank has been locked, refusing to update variable\n");
+ return OPAL_RESOURCE;
+ }
+
list_for_each(bank, var, link) {
if (!strcmp(varname, var->name)) {
goto found;
@@ -197,7 +203,6 @@ static int64_t opal_get_next_variable(uint64_t k_varname, uint64_t k_size, uint6
}
opal_call(OPAL_GET_NEXT_VARIABLE, opal_get_next_variable, 3);
-
// Cleanup function to empty out a bank list
static void clear_bank_list(struct list_head *head)
{
@@ -218,7 +223,7 @@ static int64_t opal_secboot_commit(uint64_t section)
CHECK_KEYSTORE_READY;
- if (section & ACTIVE_BANK) {
+ if ((section & ACTIVE_BANK) && (!active_lock)) {
ret = secboot_part_serialize_and_write(&active_bank_list, ACTIVE_BANK);
}
@@ -237,6 +242,24 @@ static int64_t opal_secboot_commit(uint64_t section)
opal_call(OPAL_SECBOOT_COMMIT, opal_secboot_commit, 1);
+
+// TODO: Determine and implement actual R/W mode locks
+static int64_t opal_lock_variables(uint64_t section, uint64_t mode)
+{
+ (void) mode;
+
+ CHECK_KEYSTORE_READY;
+
+ if (section == ACTIVE_BANK) {
+ active_lock = 1;
+ }
+
+ return OPAL_SUCCESS;
+}
+opal_call(OPAL_LOCK_VARIABLES, opal_lock_variables, 2);
+
+
+
int keystore_init(void)
{
int rc;
@@ -265,6 +288,7 @@ int keystore_init(void)
}
keystore_ready = true;
+ active_lock = 0;
prlog(PR_INFO, "Keystore initialized successfully\n");
--
2.14.4
More information about the Skiboot
mailing list