]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
mi-mctp: Fix free() in error path of mi_open_mctp
authorJeremy Kerr <jk@codeconstruct.com.au>
Sat, 23 Sep 2023 16:44:50 +0000 (09:44 -0700)
committerDaniel Wagner <wagi@monom.org>
Mon, 25 Sep 2023 08:59:35 +0000 (10:59 +0200)
If the malloc of our struct nvme_mi_transport_mctp fails, we'll attempt
to free ->rsp_buf of this (now zero) pointer.

Instead, structure the error path to progressively undo the
initialisation operations. This means we'll need to save the errno at
the site of each possible failure.

In doing this, add a comment to the call to nvme_mi_close(), just to
clarify behaviour with regards to the cleanups through that path.

Reported-by: Barnabás Pőcze <pobrn@protonmail.com>
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
src/nvme/mi-mctp.c

index 31462173b636d4d392e6366ede615798f63f0c97..86c4c29e2f993ae32c096d11e3495a483ab12d35 100644 (file)
@@ -472,23 +472,29 @@ nvme_mi_ep_t nvme_mi_open_mctp(nvme_root_t root, unsigned int netid, __u8 eid)
                return NULL;
 
        mctp = malloc(sizeof(*mctp));
-       if (!mctp)
-               goto err_free_ep;
+       if (!mctp) {
+               errno_save = errno;
+               goto err_close_ep;
+       }
 
        memset(mctp, 0, sizeof(*mctp));
        mctp->sd = -1;
 
        mctp->resp_buf_size = 4096;
        mctp->resp_buf = malloc(mctp->resp_buf_size);
-       if (!mctp->resp_buf)
-               goto err_free_ep;
+       if (!mctp->resp_buf) {
+               errno_save = errno;
+               goto err_free_mctp;
+       }
 
        mctp->net = netid;
        mctp->eid = eid;
 
        mctp->sd = ops.socket(AF_MCTP, SOCK_DGRAM, 0);
-       if (mctp->sd < 0)
-               goto err_free_ep;
+       if (mctp->sd < 0) {
+               errno_save = errno;
+               goto err_free_rspbuf;
+       }
 
        ep->transport = &nvme_mi_transport_mctp;
        ep->transport_data = mctp;
@@ -504,11 +510,14 @@ nvme_mi_ep_t nvme_mi_open_mctp(nvme_root_t root, unsigned int netid, __u8 eid)
 
        return ep;
 
-err_free_ep:
-       errno_save = errno;
-       nvme_mi_close(ep);
+err_free_rspbuf:
        free(mctp->resp_buf);
+err_free_mctp:
        free(mctp);
+err_close_ep:
+       /* the ep->transport is not set yet, so this will not call back
+        * into nvme_mi_mctp_close() */
+       nvme_mi_close(ep);
        errno = errno_save;
        return NULL;
 }