From 504a3324a38aefafcd40db2f1ba6c5eb5bc19761 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 7 Nov 2023 15:40:24 +0100 Subject: [PATCH 1/2] libnvme: fix a memory leak in read_discovery() In case of error, the "discovery" pointer should be freed. Signed-off-by: Maurizio Lombardi --- src/nvme/nbft.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c index 300703b6..fa61154e 100644 --- a/src/nvme/nbft.c +++ b/src/nvme/nbft.c @@ -411,26 +411,29 @@ static int read_discovery(struct nbft_info *nbft, struct nbft_discovery *raw_discovery, struct nbft_info_discovery **d) { - struct nbft_info_discovery *discovery; + struct nbft_info_discovery *discovery = NULL; struct nbft_header *header = (struct nbft_header *)nbft->raw_nbft; + int r = -EINVAL; if (!(raw_discovery->flags & NBFT_DISCOVERY_VALID)) - return -EINVAL; + goto error; verify(raw_discovery->structure_id == NBFT_DESC_DISCOVERY, "invalid ID in discovery descriptor"); discovery = calloc(1, sizeof(struct nbft_info_discovery)); - if (!discovery) - return -ENOMEM; + if (!discovery) { + r = -ENOMEM; + goto error; + } discovery->index = raw_discovery->index; if (get_heap_obj(raw_discovery, discovery_ctrl_addr_obj, 1, &discovery->uri)) - return -EINVAL; + goto error; if (get_heap_obj(raw_discovery, discovery_ctrl_nqn_obj, 1, &discovery->nqn)) - return -EINVAL; + goto error; discovery->hfi = hfi_from_index(nbft, raw_discovery->hfi_index); if (raw_discovery->hfi_index && !discovery->hfi) @@ -445,7 +448,12 @@ static int read_discovery(struct nbft_info *nbft, nbft->filename, discovery->index); *d = discovery; - return 0; + r = 0; + +error: + if (r) + free(discovery); + return r; } static int read_security(struct nbft_info *nbft, From 5bbc7b287087cb54bbcf6d08fc3ac2dcfa851014 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 7 Nov 2023 15:51:55 +0100 Subject: [PATCH 2/2] libnvme: fix a memory leak when calling read_ssns() If the check fails, the verify() macro executes "return -EINVAL" without freeing the allocated memory. Fix the bug by moving verify() before the point where we call calloc(). Signed-off-by: Maurizio Lombardi --- src/nvme/nbft.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c index fa61154e..2c870880 100644 --- a/src/nvme/nbft.c +++ b/src/nvme/nbft.c @@ -197,15 +197,15 @@ static int read_ssns(struct nbft_info *nbft, verify(raw_ssns->structure_id == NBFT_DESC_SSNS, "invalid ID in SSNS descriptor"); + /* verify transport type */ + verify(raw_ssns->trtype == NBFT_TRTYPE_TCP, + "invalid transport type in SSNS descriptor"); + ssns = calloc(1, sizeof(*ssns)); if (!ssns) return -ENOMEM; ssns->index = le16_to_cpu(raw_ssns->index); - - /* transport type */ - verify(raw_ssns->trtype == NBFT_TRTYPE_TCP, - "invalid transport type in SSNS descriptor"); strncpy(ssns->transport, trtype_to_string(raw_ssns->trtype), sizeof(ssns->transport)); /* transport specific flags */