]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsmem: fix, using freed memory
authorRuediger Meier <ruediger.meier@ga-group.nl>
Tue, 27 Jun 2017 18:33:18 +0000 (20:33 +0200)
committerRuediger Meier <ruediger.meier@ga-group.nl>
Thu, 29 Jun 2017 12:04:18 +0000 (14:04 +0200)
Simply avoiding strdup(). Error handling improved.

This was the Clang Analyzer warning:

    Memory Error, Use-after-free
    sys-utils/lsmem.c:259:3: warning: Use of memory after it is freed
                    err(EXIT_FAILURE, _("Failed to open %s"), path);
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
include/path.h
lib/path.c
sys-utils/lscpu.c
sys-utils/lsmem.c

index 11c3367596e4f4e96de0fa1fb857d7b0cf2dced7..ae36d7f4c91baefc4f35330f3513dd0fb3b67d3a 100644 (file)
@@ -4,8 +4,11 @@
 #include <stdio.h>
 #include <stdint.h>
 
-extern char *path_strdup(const char *path, ...)
+/* Returns a pointer to a static buffer which may be destroyed by any later
+path_* function call. NULL means error and errno will be set. */
+extern const char *path_get(const char *path, ...)
                        __attribute__ ((__format__ (__printf__, 1, 2)));
+
 extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...)
                        __attribute__ ((__format__ (__printf__, 3, 4)));
 extern void path_read_str(char *result, size_t len, const char *path, ...)
index 3c587e43332c24b48f7c868e2f87f09c3f1e45ee..79c1e7a6816a1e92a36082d0ab6d63f3af4f2dab 100644 (file)
@@ -50,8 +50,8 @@ path_vcreate(const char *path, va_list ap)
        return pathbuf;
 }
 
-char *
-path_strdup(const char *path, ...)
+const char *
+path_get(const char *path, ...)
 {
        const char *p;
        va_list ap;
@@ -60,7 +60,7 @@ path_strdup(const char *path, ...)
        p = path_vcreate(path, ap);
        va_end(ap);
 
-       return p ? strdup(p) : NULL;
+       return p;
 }
 
 static FILE *
index f6e47277eae87054899e1a2b4f209cd0f25494c0..83f3a7d2791e28e4f0b2360ca5cb3fce29684fa5 100644 (file)
@@ -1430,12 +1430,12 @@ read_nodes(struct lscpu_desc *desc)
        int i = 0;
        DIR *dir;
        struct dirent *d;
-       char *path;
+       const char *path;
 
        /* number of NUMA node */
-       path = path_strdup(_PATH_SYS_NODE);
+       if (!(path = path_get(_PATH_SYS_NODE)))
+               return;
        dir = opendir(path);
-       free(path);
 
        while (dir && (d = readdir(dir))) {
                if (is_node_dirent(d))
index e1ee5a5ce0c516558131c3024f41097904057e08..4db6789666ec197e4cf2f0bf2b893105bc6f538b 100644 (file)
@@ -248,15 +248,14 @@ static void print_summary(struct lsmem *lsmem)
 static int memory_block_get_node(char *name)
 {
        struct dirent *de;
-       char *path;
+       const char *path;
        DIR *dir;
        int node;
 
-       path = path_strdup(_PATH_SYS_MEMORY"/%s", name);
-       dir = opendir(path);
-       free(path);
-       if (!dir)
-               err(EXIT_FAILURE, _("Failed to open %s"), path);
+       path = path_get(_PATH_SYS_MEMORY"/%s", name);
+       if (!path || !(dir= opendir(path)))
+               err(EXIT_FAILURE, _("Failed to open %s"), path ? path : name);
+
        node = -1;
        while ((de = readdir(dir)) != NULL) {
                if (strncmp("node", de->d_name, 4))
@@ -348,14 +347,16 @@ static int memory_block_filter(const struct dirent *de)
 
 static void read_basic_info(struct lsmem *lsmem)
 {
-       char *dir;
+       const char *dir;
 
        if (!path_exist(_PATH_SYS_MEMORY_BLOCK_SIZE))
                errx(EXIT_FAILURE, _("This system does not support memory blocks"));
 
-       dir = path_strdup(_PATH_SYS_MEMORY);
+       dir = path_get(_PATH_SYS_MEMORY);
+       if (!dir)
+               err(EXIT_FAILURE, _("Failed to read %s"), _PATH_SYS_MEMORY);
+
        lsmem->ndirs = scandir(dir, &lsmem->dirs, memory_block_filter, versionsort);
-       free(dir);
        if (lsmem->ndirs <= 0)
                err(EXIT_FAILURE, _("Failed to read %s"), _PATH_SYS_MEMORY);