]> www.infradead.org Git - users/hch/nvme-cli.git/commitdiff
nvme-cli: fix memory leak in ns_descs()
authorMinwoo Im <minwoo.im.dev@gmail.com>
Wed, 17 Jan 2018 11:01:57 +0000 (20:01 +0900)
committerMinwoo Im <minwoo.im.dev@gmail.com>
Wed, 17 Jan 2018 11:07:54 +0000 (20:07 +0900)
Memory has been allocated before parsing command options by
parse_and_open() and validate_output_format().
Make it after the setup of options.

_nsdescs_ changes to (void *) for usability.

_nsdescs_ has been allocated without any free.
Add free statement for _nsdescs_. Please refer below memory leak.

==8533== HEAP SUMMARY:
==8533==     in use at exit: 4,096 bytes in 1 blocks
==8533==   total heap usage: 31 allocs, 30 frees, 7,906 bytes allocated
==8533==
==8533== Searching for pointers to 1 not-freed blocks
==8533== Checked 70,624 bytes
==8533==
==8533== 4,096 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8533==    at 0x4C2FFC6: memalign (in
                           /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8533==    by 0x4C300D1: posix_memalign (in
                           /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8533==    by 0x409D2D: ns_descs (nvme.c:1466)
==8533==    by 0x419567: handle_plugin (plugin.c:150)
==8533==    by 0x401890: main (nvme.c:3803)
==8533==
==8533== LEAK SUMMARY:
==8533==    definitely lost: 4,096 bytes in 1 blocks
==8533==    indirectly lost: 0 bytes in 0 blocks
==8533==      possibly lost: 0 bytes in 0 blocks
==8533==    still reachable: 0 bytes in 0 blocks
==8533==         suppressed: 0 bytes in 0 blocks
==8533==
==8533== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
nvme.c

diff --git a/nvme.c b/nvme.c
index 5fe99ce952f11d6a1794945657524985fe5078e2..5590dabb142bab63379138b656c148d5343c2008 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -1432,7 +1432,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *raw_binary = "show infos in binary format";
        const char *namespace_id = "identifier of desired namespace";
        int err, fmt, fd;
-       char *nsdescs[0x1000] = { };
+       void *nsdescs;
        struct config {
                __u32 namespace_id;
                int raw_binary;
@@ -1451,11 +1451,6 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
                {NULL}
        };
 
-       if (posix_memalign((void *)&nsdescs, getpagesize(), 0x1000)) {
-               fprintf(stderr, "can not allocate controller list payload\n");
-               return ENOMEM;
-       }
-
        fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
        if (fd < 0)
                return fd;
@@ -1468,15 +1463,20 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
        if (!cfg.namespace_id)
                cfg.namespace_id = get_nsid(fd);
 
-       err = nvme_identify_ns_descs(fd, cfg.namespace_id, &nsdescs);
+       if (posix_memalign(&nsdescs, getpagesize(), 0x1000)) {
+               fprintf(stderr, "can not allocate controller list payload\n");
+               return ENOMEM;
+       }
+
+       err = nvme_identify_ns_descs(fd, cfg.namespace_id, nsdescs);
        if (!err) {
                if (fmt == BINARY)
-                       d_raw((unsigned char *)&nsdescs, 0x1000);
+                       d_raw((unsigned char *)nsdescs, 0x1000);
                else if (fmt == JSON)
-                       json_nvme_id_ns_descs(&nsdescs);
+                       json_nvme_id_ns_descs(nsdescs);
                else {
                        printf("NVME Namespace Identification Descriptors NS %d:\n", cfg.namespace_id);
-                       show_nvme_id_ns_descs(&nsdescs);
+                       show_nvme_id_ns_descs(nsdescs);
                }
        }
        else if (err > 0)
@@ -1484,6 +1484,9 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
                        nvme_status_to_string(err), err, cfg.namespace_id);
        else
                perror("identify namespace");
+
+       free(nsdescs);
+
        return err;
 }