diff mbox series

[v6,06/20] secvar_util: add new helper functions

Message ID 20200916162131.22478-7-erichte@linux.ibm.com
State Accepted
Headers show
Series Add initial secure variable storage and backend drivers | expand

Checks

Context Check Description
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (d362ae4f4c521a7faffb1befe2fbba467f2c4d18)

Commit Message

Eric Richter Sept. 16, 2020, 4:21 p.m. UTC
This patch adds the following helper functions:
 - dealloc_secvar()
 - new_secvar()
 - copy_bank_list()

dealloc_secvar() frees a whole secvar_node reference including
its children allocations. This also updates the clear_bank_list()
helper function to use this destructor.

new_secvar() allocates a secvar_node, and fills it with data
provided via arguments.

copy_bank_list() creates a deep copy of a secvar bank list

Signed-off-by: Eric Richter <erichte@linux.ibm.com>
---
 libstb/secvar/secvar.h      |  5 +++
 libstb/secvar/secvar_util.c | 63 +++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/libstb/secvar/secvar.h b/libstb/secvar/secvar.h
index a0cafbb0..b141b705 100644
--- a/libstb/secvar/secvar.h
+++ b/libstb/secvar/secvar.h
@@ -43,8 +43,13 @@  extern struct secvar_backend_driver secvar_backend;
 
 // Helper functions
 void clear_bank_list(struct list_head *bank);
+int copy_bank_list(struct list_head *dst, struct list_head *src);
 struct secvar_node *alloc_secvar(uint64_t size);
+struct secvar_node *new_secvar(const char *key, uint64_t key_len,
+			       const char *data, uint64_t data_size,
+			       uint64_t flags);
 int realloc_secvar(struct secvar_node *node, uint64_t size);
+void dealloc_secvar(struct secvar_node *node);
 struct secvar_node *find_secvar(const char *key, uint64_t key_len, struct list_head *bank);
 int is_key_empty(const char *key, uint64_t key_len);
 int list_length(struct list_head *bank);
diff --git a/libstb/secvar/secvar_util.c b/libstb/secvar/secvar_util.c
index 2005de58..3aadbd98 100644
--- a/libstb/secvar/secvar_util.c
+++ b/libstb/secvar/secvar_util.c
@@ -20,11 +20,31 @@  void clear_bank_list(struct list_head *bank)
 
 	list_for_each_safe(bank, node, next, link) {
 		list_del(&node->link);
+		dealloc_secvar(node);
+	}
+}
+
+int copy_bank_list(struct list_head *dst, struct list_head *src)
+{
+	struct secvar_node *node, *tmp;
 
-		if (node->var)
-			free(node->var);
-		free(node);
+	list_for_each(src, node, link) {
+		/* Allocate new secvar using actual data size */
+		tmp = alloc_secvar(node->var->data_size);
+		if (!tmp)
+			return OPAL_NO_MEM;
+
+		/* Copy over flags metadata */
+		tmp->flags = node->flags;
+
+		/* Full-clone over the secvar struct */
+		memcpy(tmp->var, node->var, tmp->size + sizeof(struct secvar));
+
+		/* Append to new list */
+		list_add_tail(dst, &tmp->link);
 	}
+
+	return OPAL_SUCCESS;
 }
 
 struct secvar_node *alloc_secvar(uint64_t size)
@@ -46,6 +66,34 @@  struct secvar_node *alloc_secvar(uint64_t size)
 	return ret;
 }
 
+struct secvar_node *new_secvar(const char *key, uint64_t key_len,
+			       const char *data, uint64_t data_size,
+			       uint64_t flags)
+{
+	struct secvar_node *ret;
+
+	if (!key)
+		return NULL;
+	if ((!key_len) || (key_len > SECVAR_MAX_KEY_LEN))
+		return NULL;
+	if ((!data) && (data_size))
+		return NULL;
+
+	ret = alloc_secvar(data_size);
+	if (!ret)
+		return NULL;
+
+	ret->var->key_len = key_len;
+	ret->var->data_size = data_size;
+	memcpy(ret->var->key, key, key_len);
+	ret->flags = flags;
+
+	if (data)
+		memcpy(ret->var->data, data, data_size);
+
+	return ret;
+}
+
 int realloc_secvar(struct secvar_node *node, uint64_t size)
 {
 	void *tmp;
@@ -64,6 +112,15 @@  int realloc_secvar(struct secvar_node *node, uint64_t size)
 	return 0;
 }
 
+void dealloc_secvar(struct secvar_node *node)
+{
+	if (!node)
+		return;
+
+	free(node->var);
+	free(node);
+}
+
 struct secvar_node *find_secvar(const char *key, uint64_t key_len, struct list_head *bank)
 {
 	struct secvar_node *node = NULL;