From 6350f050d5383674558dea9ec13013a4e6db4401 Mon Sep 17 00:00:00 2001 From: Flavien Solt Date: Wed, 1 Jul 2026 11:43:07 +0800 Subject: [PATCH 1/2] Cf. https://github.com/linux-nvme/libnvme/pull/1112 --- libnvme/src/nvme/nbft.c | 74 ++++++++++++++++++++++++++++++++++++++++- libnvme/src/nvme/nbft.h | 15 ++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/libnvme/src/nvme/nbft.c b/libnvme/src/nvme/nbft.c index e1af8d00c6..3dda206d2f 100644 --- a/libnvme/src/nvme/nbft.c +++ b/libnvme/src/nvme/nbft.c @@ -124,6 +124,31 @@ static int __get_heap_obj(struct libnvme_global_ctx *ctx, descriptor->obj, is_string, \ output) +/* Point at a raw (non-string) heap object and return its length. */ +static int __get_heap_obj_raw(struct libnvme_global_ctx *ctx, + struct nbft_header *header, const char *filename, + const char *descriptorname, const char *fieldname, + struct nbft_heap_obj obj, unsigned char **output, __u16 *length) +{ + *output = NULL; + *length = le16_to_cpu(obj.length); + if (*length == 0) + return 0; + if (!in_heap(header, obj)) { + libnvme_msg(ctx, LIBNVME_LOG_DEBUG, + "file %s: field '%s' in descriptor '%s' has invalid offset or length\n", + filename, fieldname, descriptorname); + return -EINVAL; + } + *output = (unsigned char *)header + le32_to_cpu(obj.offset); + return 0; +} + +#define get_heap_obj_raw(descriptor, obj, output, length) \ + __get_heap_obj_raw(ctx, header, nbft->filename, \ + stringify(descriptor), stringify(obj), \ + descriptor->obj, output, length) + static struct libnbft_discovery *discovery_from_index(struct libnbft_info *nbft, int i) { @@ -510,7 +535,54 @@ static int read_security(struct libnvme_global_ctx *ctx, struct libnbft_info *nb struct nbft_security *raw_security, struct libnbft_security **s) { - return -EINVAL; + struct nbft_header *header = (struct nbft_header *)nbft->raw_nbft; + struct libnbft_security *security; + __u16 flags = le16_to_cpu(raw_security->flags); + int ret; + + if (!(flags & NBFT_SECURITY_VALID)) + return -EINVAL; + verify(ctx, raw_security->structure_id == NBFT_DESC_SECURITY, + "invalid ID in security descriptor"); + + security = calloc(1, sizeof(*security)); + if (!security) + return -ENOMEM; + + security->index = raw_security->index; + security->flags = flags; + security->secret_type = raw_security->secret_type; + + /* policy lists point into the raw NBFT heap */ + ret = get_heap_obj_raw(raw_security, sec_chan_alg_obj, + &security->sec_chan_alg, &security->sec_chan_alg_len); + if (!ret) + ret = get_heap_obj_raw(raw_security, auth_proto_obj, + &security->auth_proto, &security->auth_proto_len); + if (!ret) + ret = get_heap_obj_raw(raw_security, cipher_suite_obj, + &security->cipher_suite, &security->cipher_suite_len); + if (!ret) + ret = get_heap_obj_raw(raw_security, dh_grp_obj, + &security->dh_grp, &security->dh_grp_len); + if (!ret) + ret = get_heap_obj_raw(raw_security, sec_hash_func_obj, + &security->sec_hash_func, &security->sec_hash_func_len); + if (ret) { + free(security); + return ret; + } + + /* keypath URI also points into the heap; absent is fine */ + ret = get_heap_obj(ctx, raw_security, sec_keypath_obj, 1, + &security->sec_keypath); + if (ret && ret != -ENOENT) { + free(security); + return ret; + } + + *s = security; + return 0; } static void read_hfi_descriptors(struct libnvme_global_ctx *ctx, diff --git a/libnvme/src/nvme/nbft.h b/libnvme/src/nvme/nbft.h index f9c6a572f0..12ca4122b2 100644 --- a/libnvme/src/nvme/nbft.h +++ b/libnvme/src/nvme/nbft.h @@ -147,7 +147,20 @@ struct libnbft_discovery { */ struct libnbft_security { int index; - /* TODO add fields */ + __u16 flags; + __u8 secret_type; + /* list fields point into the raw NBFT; not separately freed */ + unsigned char *sec_chan_alg; + __u16 sec_chan_alg_len; + unsigned char *auth_proto; + __u16 auth_proto_len; + unsigned char *cipher_suite; + __u16 cipher_suite_len; + unsigned char *dh_grp; + __u16 dh_grp_len; + unsigned char *sec_hash_func; + __u16 sec_hash_func_len; + char *sec_keypath; }; /** From c86bb84f4aacfde759c617d5306c4f44440ec17c Mon Sep 17 00:00:00 2001 From: Flavien Solt Date: Wed, 1 Jul 2026 14:20:51 +0800 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- libnvme/src/nvme/nbft.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libnvme/src/nvme/nbft.c b/libnvme/src/nvme/nbft.c index 3dda206d2f..b528a83c88 100644 --- a/libnvme/src/nvme/nbft.c +++ b/libnvme/src/nvme/nbft.c @@ -553,19 +553,23 @@ static int read_security(struct libnvme_global_ctx *ctx, struct libnbft_info *nb security->flags = flags; security->secret_type = raw_security->secret_type; - /* policy lists point into the raw NBFT heap */ - ret = get_heap_obj_raw(raw_security, sec_chan_alg_obj, - &security->sec_chan_alg, &security->sec_chan_alg_len); - if (!ret) + /* policy lists point into the raw NBFT heap (only when indicated by flags) */ + ret = 0; + if ((flags & NBFT_SECURITY_SEC_POLICY_LIST_MASK) != + NBFT_SECURITY_SEC_POLICY_LIST_NOT_SUPPORTED) + ret = get_heap_obj_raw(raw_security, sec_chan_alg_obj, + &security->sec_chan_alg, &security->sec_chan_alg_len); + if (!ret && (flags & NBFT_SECURITY_AUTH_POLICY_LIST_MASK) != + NBFT_SECURITY_AUTH_POLICY_LIST_NOT_SUPPORTED) ret = get_heap_obj_raw(raw_security, auth_proto_obj, &security->auth_proto, &security->auth_proto_len); - if (!ret) + if (!ret && (flags & NBFT_SECURITY_CIPHER_RESTRICTED)) ret = get_heap_obj_raw(raw_security, cipher_suite_obj, &security->cipher_suite, &security->cipher_suite_len); - if (!ret) + if (!ret && (flags & NBFT_SECURITY_AUTH_DH_GROUPS_RESTRICTED)) ret = get_heap_obj_raw(raw_security, dh_grp_obj, &security->dh_grp, &security->dh_grp_len); - if (!ret) + if (!ret && (flags & NBFT_SECURITY_SEC_HASH_FUNC_POLICY_LIST)) ret = get_heap_obj_raw(raw_security, sec_hash_func_obj, &security->sec_hash_func, &security->sec_hash_func_len); if (ret) {