kmodloader: fix memory leak in scan_loaded_modules()
[project/ubox.git] / kmodloader.c
index 26926a021be474bac5fd7e9db07aa8b79e43602a..0afc79560693e9a67bf0ca74a0dfd934b5387e75 100644 (file)
@@ -311,12 +311,13 @@ static int scan_loaded_modules(void)
 {
        size_t buf_len = 0;
        char *buf = NULL;
+       int rv = -1;
        FILE *fp;
 
        fp = fopen("/proc/modules", "r");
        if (!fp) {
                ULOG_ERR("failed to open /proc/modules\n");
-               return -1;
+               goto out;
        }
 
        while (getline(&buf, &buf_len, fp) > 0) {
@@ -336,13 +337,20 @@ static int scan_loaded_modules(void)
                        /* possibly a module outside /lib/modules/<ver>/ */
                        n = alloc_module(m.name, NULL, 0, m.depends, m.size);
                }
+               if (!n) {
+                       ULOG_ERR("Failed to allocate memory for module\n");
+                       goto out;
+               }
+
                n->usage = m.usage;
                n->state = LOADED;
        }
+       rv = 0;
+out:
        free(buf);
        fclose(fp);
 
-       return 0;
+       return rv;
 }
 
 static struct module* get_module_info(const char *module, const char *name)
@@ -351,6 +359,7 @@ static struct module* get_module_info(const char *module, const char *name)
        unsigned int offset, size;
        char *map = MAP_FAILED, *strings, *dep = NULL;
        const char **aliases = NULL;
+       const char **aliasesr;
        int naliases = 0;
        struct module *m = NULL;
        struct stat s;
@@ -393,12 +402,13 @@ static struct module* get_module_info(const char *module, const char *name)
                if (!strncmp(strings, "depends=", len + 1))
                        dep = sep;
                else if (!strncmp(strings, "alias=", len + 1)) {
-                       aliases = realloc(aliases, sizeof(sep) * (naliases + 1));
-                       if (!aliases) {
+                       aliasesr = realloc(aliases, sizeof(sep) * (naliases + 1));
+                       if (!aliasesr) {
                                ULOG_ERR("out of memory\n");
                                goto out;
                        }
 
+                       aliases = aliasesr;
                        aliases[naliases++] = sep;
                }
                strings = &sep[strlen(sep)];
@@ -424,12 +434,10 @@ out:
 static int scan_module_folder(const char *dir)
 {
        int gl_flags = GLOB_NOESCAPE | GLOB_MARK;
-       struct utsname ver;
        char *path;
        glob_t gl;
        int j, rv = 0;
 
-       uname(&ver);
        path = alloca(strlen(dir) + sizeof("*.ko") + 1);
        sprintf(path, "%s*.ko", dir);
 
@@ -581,6 +589,11 @@ static int insert_module(char *path, const char *options)
        struct stat s;
        int fd, ret = -1;
 
+       if (!path) {
+               ULOG_ERR("Path not specified\n");
+               return ret;
+       }
+
        if (stat(path, &s)) {
                ULOG_ERR("missing module %s\n", path);
                return ret;
@@ -965,7 +978,7 @@ static int main_loader(int argc, char **argv)
        struct module *m;
        glob_t gl;
        char *path;
-       int fail, j;
+       int ret = 0, fail, j;
 
        if (argc > 1)
                dir = argv[1];
@@ -980,13 +993,13 @@ static int main_loader(int argc, char **argv)
        strcat(path, "*");
 
        if (scan_module_folders()) {
-               free (path);
-               return -1;
+               ret = -1;
+               goto free_path;
        }
 
        if (scan_loaded_modules()) {
-               free (path);
-               return -1;
+               ret = -1;
+               goto free_path;
        }
 
        ULOG_INFO("loading kernel modules from %s\n", path);
@@ -1024,8 +1037,15 @@ static int main_loader(int argc, char **argv)
                                if (m->opts) {
                                        char *prev = m->opts;
 
-                                       asprintf(&m->opts, "%s %s", prev, opts);
+                                       fail = asprintf(&m->opts, "%s %s", prev, opts);
                                        free(prev);
+                                       if (fail < 0) {
+                                               ULOG_ERR("out of memory for opts %s\n", opts);
+                                               free(mod);
+                                               fclose(fp);
+                                               ret = -1;
+                                               goto out;
+                                       }
                                } else {
                                        m->opts = strdup(opts);
                                }
@@ -1058,9 +1078,10 @@ static int main_loader(int argc, char **argv)
 
 out:
        globfree(&gl);
+free_path:
        free(path);
 
-       return 0;
+       return ret;
 }
 
 static inline char weight(char c)
@@ -1154,6 +1175,8 @@ load_options(void)
                        continue;
                }
        }
+
+       fclose(f);
 }
 
 int main(int argc, char **argv)