From patchwork Wed Sep 16 16:21:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Richter X-Patchwork-Id: 1365447 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Bs54m2rxPz9sTS for ; Thu, 17 Sep 2020 02:23:36 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=nV8j71o2; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4Bs54l5ySKzDqXr for ; Thu, 17 Sep 2020 02:23:35 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0b-001b2d01.pphosted.com; envelope-from=erichte@linux.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=nV8j71o2; dkim-atps=neutral Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Bs52k3Z23zDqLw for ; Thu, 17 Sep 2020 02:21:50 +1000 (AEST) Received: from pps.filterd (m0127361.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 08GG5O7J004390 for ; Wed, 16 Sep 2020 12:21:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=3fSzymun4StSS5EruobujT7DCpCQt8n5dlh2PIU2x+I=; b=nV8j71o2gKoK4kb8ArFYMKKJ+LwgObELveKqcvW/7fCAzgeMTJB3e3KeyUJnafdIhwVA BZ33K6l+FIq4fwCbov7T7TwtkjCEQI7mbnoE1qNkBkiFZQ4jX81auzwK+4SM9MzEllp8 8XXJLqqO8/vzsiOO1jAp3wg61baCHfRePU0QMIqsdJ00TeISDkmc1Sk0YzQK+8qbwtJJ QiDYYMIi21PTW5o1F2VQ3/z1shYS2B3CZXupLfP5X55UFLnFHNySF0IEwA1QvUQOLhvr 15+34GLkd6wYGohwqZ8zEUOmLObTOLalxjutM3Br1+NZ+xYz/ELqxVV/aPO+dDQa8xVi zw== Received: from ppma02fra.de.ibm.com (47.49.7a9f.ip4.static.sl-reverse.com [159.122.73.71]) by mx0a-001b2d01.pphosted.com with ESMTP id 33knuygfqj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Sep 2020 12:21:47 -0400 Received: from pps.filterd (ppma02fra.de.ibm.com [127.0.0.1]) by ppma02fra.de.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 08GGJ7Ft007815 for ; Wed, 16 Sep 2020 16:21:45 GMT Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by ppma02fra.de.ibm.com with ESMTP id 33k623ge6s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 16 Sep 2020 16:21:45 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 08GGLgWn29884708 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 16 Sep 2020 16:21:43 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D93EE11C04A; Wed, 16 Sep 2020 16:21:42 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 17B2E11C04C; Wed, 16 Sep 2020 16:21:42 +0000 (GMT) Received: from ceres.ibmuc.com (unknown [9.160.109.67]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 16 Sep 2020 16:21:41 +0000 (GMT) From: Eric Richter To: skiboot@lists.ozlabs.org Date: Wed, 16 Sep 2020 11:21:18 -0500 Message-Id: <20200916162131.22478-8-erichte@linux.ibm.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20200916162131.22478-1-erichte@linux.ibm.com> References: <20200916162131.22478-1-erichte@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687 definitions=2020-09-16_10:2020-09-16, 2020-09-16 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 clxscore=1015 mlxscore=0 malwarescore=0 priorityscore=1501 adultscore=0 phishscore=0 bulkscore=0 impostorscore=0 lowpriorityscore=0 mlxlogscore=999 suspectscore=3 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2006250000 definitions=main-2009160116 Subject: [Skiboot] [PATCH v6 07/20] secvar: overhaul secvar struct by removing static sized fields X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nayna@linux.ibm.com Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Eric Richter Originally, the secvar struct was intended to contain all the variable information seperate from the linked list/etc metadata, so that copying and serialization/deserialization could be handled by a single memcpy(). This is fragile, potentially compiler dependent, and doesn't account for endianness. Therefore, this patch removes the static allocation for key, now allocates a buffer for data, and completely removes the now unnecessary secvar_node struct. As a side effect, some of the secvar_util functionality has been tweaked where it makes sense. Most notably alloc_secvar now takes in an extra argument as it now has to allocate the key Signed-off-by: Eric Richter --- libstb/secvar/secvar.h | 24 ++++------ libstb/secvar/secvar_api.c | 68 +++++++++++++-------------- libstb/secvar/secvar_util.c | 93 ++++++++++++++++++------------------- 3 files changed, 88 insertions(+), 97 deletions(-) diff --git a/libstb/secvar/secvar.h b/libstb/secvar/secvar.h index b141b705..fe660217 100644 --- a/libstb/secvar/secvar.h +++ b/libstb/secvar/secvar.h @@ -16,24 +16,18 @@ enum { }; -struct secvar_node { - struct list_node link; - struct secvar *var; - uint64_t flags; // Flag for how *var should be stored - uint64_t size; // How much space was allocated for data -}; - #define SECVAR_FLAG_VOLATILE 0x1 // Instructs storage driver to ignore variable on writes #define SECVAR_FLAG_SECURE_STORAGE 0x2 // Hint for storage driver to select storage location struct secvar { + struct list_node link; uint64_t key_len; uint64_t data_size; - char key[SECVAR_MAX_KEY_LEN]; - char data[0]; + uint64_t flags; + char *key; + char *data; }; - extern struct list_head variable_bank; extern struct list_head update_bank; extern int secvar_enabled; @@ -44,13 +38,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, +struct secvar *alloc_secvar(uint64_t key_len, uint64_t data_size); +struct secvar *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 realloc_secvar(struct secvar *node, uint64_t size); +void dealloc_secvar(struct secvar *node); +struct secvar *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_api.c b/libstb/secvar/secvar_api.c index 62c32500..7245e859 100644 --- a/libstb/secvar/secvar_api.c +++ b/libstb/secvar/secvar_api.c @@ -11,7 +11,7 @@ static int64_t opal_secvar_get(const char *key, uint64_t key_len, void *data, uint64_t *data_size) { - struct secvar_node *node; + struct secvar *var; int64_t rc = OPAL_SUCCESS; if (!secvar_enabled) @@ -26,18 +26,18 @@ static int64_t opal_secvar_get(const char *key, uint64_t key_len, void *data, ui if (!data_size) return OPAL_PARAMETER; - node = find_secvar(key, key_len, &variable_bank); - if (!node) + var = find_secvar(key, key_len, &variable_bank); + if (!var) return OPAL_EMPTY; // Variable not found, bail early if (!data) rc = OPAL_SUCCESS; - else if (*data_size < node->var->data_size) + else if (*data_size < var->data_size) rc = OPAL_PARTIAL; else - memcpy(data, node->var->data, node->var->data_size); + memcpy(data, var->data, var->data_size); - *data_size = node->var->data_size; + *data_size = var->data_size; return rc; } @@ -46,7 +46,7 @@ opal_call(OPAL_SECVAR_GET, opal_secvar_get, 4); static int64_t opal_secvar_get_next(char *key, uint64_t *key_len, uint64_t key_buf_size) { - struct secvar_node *node; + struct secvar *var; if (!secvar_enabled) return OPAL_UNSUPPORTED; @@ -64,25 +64,25 @@ static int64_t opal_secvar_get_next(char *key, uint64_t *key_len, uint64_t key_b return OPAL_PARAMETER; if (!is_key_empty(key, *key_len)) { - node = find_secvar(key, *key_len, &variable_bank); - if (!node) + var = find_secvar(key, *key_len, &variable_bank); + if (!var) return OPAL_PARAMETER; - node = list_next(&variable_bank, node, link); + var = list_next(&variable_bank, var, link); } else { - node = list_top(&variable_bank, struct secvar_node, link); + var = list_top(&variable_bank, struct secvar, link); } - if (!node) + if (!var) return OPAL_EMPTY; - if (key_buf_size < node->var->key_len) { - *key_len = node->var->key_len; + if (key_buf_size < var->key_len) { + *key_len = var->key_len; return OPAL_PARTIAL; } - *key_len = node->var->key_len; - memcpy(key, node->var->key, node->var->key_len); + *key_len = var->key_len; + memcpy(key, var->key, var->key_len); return OPAL_SUCCESS; } @@ -91,7 +91,7 @@ opal_call(OPAL_SECVAR_GET_NEXT, opal_secvar_get_next, 3); static int64_t opal_secvar_enqueue_update(const char *key, uint64_t key_len, void *data, uint64_t data_size) { - struct secvar_node *node; + struct secvar *var; if (!secvar_enabled) return OPAL_UNSUPPORTED; @@ -114,41 +114,39 @@ static int64_t opal_secvar_enqueue_update(const char *key, uint64_t key_len, voi if (is_key_empty(key, key_len)) return OPAL_PARAMETER; - node = find_secvar(key, key_len, &update_bank); + var = find_secvar(key, key_len, &update_bank); // Unstage an update if (data_size == 0) { - if (!node) + if (!var) return OPAL_EMPTY; - if (node->var) - free(node->var); - list_del(&node->link); - free(node); + list_del(&var->link); + dealloc_secvar(var); goto out; } - if (node) { - list_del(&node->link); + if (var) { + list_del(&var->link); // Realloc var if too small - if (node->size < data_size) { - if (realloc_secvar(node, data_size)) + if (var->data_size < data_size) { + if (realloc_secvar(var, data_size)) return OPAL_NO_MEM; } else { - memset(node->var, 0x00, sizeof(struct secvar) + node->var->data_size); + memset(var->data, 0x00, var->data_size); } } else { - node = alloc_secvar(data_size); - if (!node) + var = alloc_secvar(key_len, data_size); + if (!var) return OPAL_NO_MEM; } - memcpy(node->var->key, key, key_len); - node->var->key_len = key_len; - memcpy(node->var->data, data, data_size); - node->var->data_size = data_size; + memcpy(var->key, key, key_len); + var->key_len = key_len; + memcpy(var->data, data, data_size); + var->data_size = data_size; - list_add_tail(&update_bank, &node->link); + list_add_tail(&update_bank, &var->link); out: if (secvar_storage.write_bank(&update_bank, SECVAR_UPDATE_BANK)) diff --git a/libstb/secvar/secvar_util.c b/libstb/secvar/secvar_util.c index 3aadbd98..533170a3 100644 --- a/libstb/secvar/secvar_util.c +++ b/libstb/secvar/secvar_util.c @@ -13,33 +13,25 @@ void clear_bank_list(struct list_head *bank) { - struct secvar_node *node, *next; + struct secvar *var, *next; if (!bank) return; - list_for_each_safe(bank, node, next, link) { - list_del(&node->link); - dealloc_secvar(node); + list_for_each_safe(bank, var, next, link) { + list_del(&var->link); + dealloc_secvar(var); } } int copy_bank_list(struct list_head *dst, struct list_head *src) { - struct secvar_node *node, *tmp; + struct secvar *var, *tmp; - list_for_each(src, node, link) { + list_for_each(src, var, 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)); - + tmp = new_secvar(var->key, var->key_len, var->data, + var->data_size, var->flags); /* Append to new list */ list_add_tail(dst, &tmp->link); } @@ -47,30 +39,38 @@ int copy_bank_list(struct list_head *dst, struct list_head *src) return OPAL_SUCCESS; } -struct secvar_node *alloc_secvar(uint64_t size) +struct secvar *alloc_secvar(uint64_t key_len, uint64_t data_size) { - struct secvar_node *ret; + struct secvar *ret; - ret = zalloc(sizeof(struct secvar_node)); + ret = zalloc(sizeof(struct secvar)); if (!ret) return NULL; - ret->var = zalloc(sizeof(struct secvar) + size); - if (!ret->var) { + ret->key = zalloc(key_len); + if (!ret->key) { + free(ret->key); + return NULL; + } + + ret->data = zalloc(data_size); + if (!ret->data) { + free(ret->key); free(ret); return NULL; } - ret->size = size; + ret->key_len = key_len; + ret->data_size = data_size; return ret; } -struct secvar_node *new_secvar(const char *key, uint64_t key_len, +struct secvar *new_secvar(const char *key, uint64_t key_len, const char *data, uint64_t data_size, uint64_t flags) { - struct secvar_node *ret; + struct secvar *ret; if (!key) return NULL; @@ -79,58 +79,57 @@ struct secvar_node *new_secvar(const char *key, uint64_t key_len, if ((!data) && (data_size)) return NULL; - ret = alloc_secvar(data_size); + ret = alloc_secvar(key_len, 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); + memcpy(ret->key, key, key_len); ret->flags = flags; if (data) - memcpy(ret->var->data, data, data_size); + memcpy(ret->data, data, data_size); return ret; } -int realloc_secvar(struct secvar_node *node, uint64_t size) +int realloc_secvar(struct secvar *var, uint64_t size) { void *tmp; - if (node->size >= size) + if (var->data_size >= size) return 0; - tmp = zalloc(sizeof(struct secvar) + size); + tmp = zalloc(size); if (!tmp) return -1; - memcpy(tmp, node->var, sizeof(struct secvar) + node->size); - free(node->var); - node->var = tmp; + memcpy(tmp, var->data, var->data_size); + free(var->data); + var->data = tmp; return 0; } -void dealloc_secvar(struct secvar_node *node) +void dealloc_secvar(struct secvar *var) { - if (!node) + if (!var) return; - free(node->var); - free(node); + free(var->key); + free(var->data); + free(var); } -struct secvar_node *find_secvar(const char *key, uint64_t key_len, struct list_head *bank) +struct secvar *find_secvar(const char *key, uint64_t key_len, struct list_head *bank) { - struct secvar_node *node = NULL; + struct secvar *var = NULL; - list_for_each(bank, node, link) { + list_for_each(bank, var, link) { // Prevent matching shorter key subsets / bail early - if (key_len != node->var->key_len) + if (key_len != var->key_len) continue; - if (!memcmp(key, node->var->key, key_len)) - return node; + if (!memcmp(key, var->key, key_len)) + return var; } return NULL; @@ -150,9 +149,9 @@ int is_key_empty(const char *key, uint64_t key_len) int list_length(struct list_head *bank) { int ret = 0; - struct secvar_node *node; + struct secvar *var; - list_for_each(bank, node, link) + list_for_each(bank, var, link) ret++; return ret;