From 06310e0302af3fe07f4cc9a902c644b1e6e45e56 Mon Sep 17 00:00:00 2001 From: Laraib Javed Date: Wed, 22 Jul 2026 14:58:10 -0500 Subject: [PATCH] libnvme/test: fix use after free in test_nvmf_sanitize_addrs() If libnvme_create_ctrl() fails and returns NULL, the subsequent calls to nvmf_sanitize_addrs() and libnvme_free_ctrl() are made with a NULL pointer, resulting in a use after free. Fail the test immediately when controller creation fails by checking the returned pointer with CHECK() and returning false, so the cause of any setup failure is immediately visible without proceeding with invalid state. Coverity CID: 561730 (Use after free) Signed-off-by: Laraib Javed --- libnvme/test/test-fabrics.c | 48 +++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/libnvme/test/test-fabrics.c b/libnvme/test/test-fabrics.c index 5d4e3080f7..be9ed2d385 100644 --- a/libnvme/test/test-fabrics.c +++ b/libnvme/test/test-fabrics.c @@ -488,9 +488,11 @@ static bool test_nvmf_sanitize_addrs(struct libnvme_global_ctx *ctx) params.subsysnqn = "nqn.2024-01.com.example:test"; params.traddr = "192.168.1.10"; params.host_traddr = "storage.example.com"; - ret = libnvme_create_ctrl(ctx, ¶ms, &c); - p = !ret && c && !strcmp(libnvme_ctrl_get_host_traddr(c), - "storage.example.com"); + libnvme_create_ctrl(ctx, ¶ms, &c); + CHECK(c, "ctrl created with hostname host_traddr"); + if (!c) + return false; + p = !strcmp(libnvme_ctrl_get_host_traddr(c), "storage.example.com"); CHECK(p, "hostname host_traddr stored verbatim at creation"); pass &= p; @@ -504,10 +506,10 @@ static bool test_nvmf_sanitize_addrs(struct libnvme_global_ctx *ctx) /* A hostname traddr is rejected the same way. */ params.traddr = "storage.example.com"; params.host_traddr = NULL; - ret = libnvme_create_ctrl(ctx, ¶ms, &c); - p = !ret && c != NULL; - CHECK(p, "ctrl created with hostname traddr"); - pass &= p; + libnvme_create_ctrl(ctx, ¶ms, &c); + CHECK(c, "ctrl created with hostname traddr"); + if (!c) + return false; ret = nvmf_sanitize_addrs(ctx, c); p = ret == -ENVME_CONNECT_TRADDR; @@ -518,10 +520,10 @@ static bool test_nvmf_sanitize_addrs(struct libnvme_global_ctx *ctx) /* An uncompressed IPv6 traddr is canonicalized. */ params.traddr = "2001:0db8:0000:0000:0000:0000:0000:0001"; - ret = libnvme_create_ctrl(ctx, ¶ms, &c); - p = !ret && c != NULL; - CHECK(p, "ctrl created with uncompressed IPv6 traddr"); - pass &= p; + libnvme_create_ctrl(ctx, ¶ms, &c); + CHECK(c, "ctrl created with uncompressed IPv6 traddr"); + if (!c) + return false; ret = nvmf_sanitize_addrs(ctx, c); p = !ret && !strcmp(libnvme_ctrl_get_traddr(c), "2001:db8::1"); @@ -537,10 +539,10 @@ static bool test_nvmf_sanitize_addrs(struct libnvme_global_ctx *ctx) * call, same as host_iface. */ params.traddr = "fe80::1%nonexistent0"; - ret = libnvme_create_ctrl(ctx, ¶ms, &c); - p = !ret && c != NULL; - CHECK(p, "ctrl created with bad-zone scoped IPv6 traddr"); - pass &= p; + libnvme_create_ctrl(ctx, ¶ms, &c); + CHECK(c, "ctrl created with bad-zone scoped IPv6 traddr"); + if (!c) + return false; ret = nvmf_sanitize_addrs(ctx, c); p = !ret && !strcmp(libnvme_ctrl_get_traddr(c), "fe80::1%nonexistent0"); @@ -553,10 +555,10 @@ static bool test_nvmf_sanitize_addrs(struct libnvme_global_ctx *ctx) /* fc: a WWN traddr is left untouched (not an IP transport). */ params.transport = "fc"; params.traddr = "nn-0x1:pn-0x2"; - ret = libnvme_create_ctrl(ctx, ¶ms, &c); - p = !ret && c != NULL; - CHECK(p, "ctrl created with fc WWN traddr"); - pass &= p; + libnvme_create_ctrl(ctx, ¶ms, &c); + CHECK(c, "ctrl created with fc WWN traddr"); + if (!c) + return false; ret = nvmf_sanitize_addrs(ctx, c); p = !ret && !strcmp(libnvme_ctrl_get_traddr(c), "nn-0x1:pn-0x2"); @@ -569,10 +571,10 @@ static bool test_nvmf_sanitize_addrs(struct libnvme_global_ctx *ctx) /* loop: no traddr at all -- nothing to sanitize. */ params.transport = "loop"; params.traddr = NULL; - ret = libnvme_create_ctrl(ctx, ¶ms, &c); - p = !ret && c != NULL; - CHECK(p, "ctrl created for loop transport"); - pass &= p; + libnvme_create_ctrl(ctx, ¶ms, &c); + CHECK(c, "ctrl created for loop transport"); + if (!c) + return false; ret = nvmf_sanitize_addrs(ctx, c); p = ret == 0;