modprobe: fix a segfault when modprobe is called with no arguments at all
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 31 Oct 2008 02:04:28 +0000 (02:04 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 31 Oct 2008 02:04:28 +0000 (02:04 -0000)
function                                             old     new   delta
modprobe_main                                        559     535     -24

modutils/modprobe.c
modutils/modutils.c

index 20b9a74aabcb6dbe4ad5479909a17d2df0c72651..40a1e66270aece074b46c77badd1992795afc354 100644 (file)
@@ -203,18 +203,17 @@ int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int modprobe_main(int argc UNUSED_PARAM, char **argv)
 {
        struct utsname uts;
-       int num_modules, i, rc;
+       int rc;
+       unsigned opt;
        llist_t *options = NULL;
-       parser_t *parser;
 
        opt_complementary = "q-v:v-q";
-       getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS,
+       opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS,
                 NULL, NULL);
        argv += optind;
-       argc -= optind;
 
-       if (option_mask32 & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY |
-                            MODPROBE_OPT_SHOW_ONLY))
+       if (opt & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY |
+                               MODPROBE_OPT_SHOW_ONLY))
                bb_error_msg_and_die("not supported");
 
        /* goto modules location */
@@ -222,40 +221,44 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
        uname(&uts);
        xchdir(uts.release);
 
-       if (option_mask32 & (MODPROBE_OPT_REMOVE | MODPROBE_OPT_INSERT_ALL)) {
-               /* each parameter is a module name */
-               num_modules = argc;
-               if (num_modules == 0) {
+       if (!argv[0]) {
+               if (opt & MODPROBE_OPT_REMOVE) {
                        if (bb_delete_module(NULL, O_NONBLOCK|O_EXCL) != 0)
                                bb_perror_msg_and_die("rmmod");
-                       return EXIT_SUCCESS;
                }
-       } else {
-               /* the only module, the rest of parameters are options */
-               num_modules = 1;
+               return EXIT_SUCCESS;
+       }
+       if (!(opt & MODPROBE_OPT_INSERT_ALL)) {
+               /* If not -a, we have only one module name,
+                * the rest of parameters are options */
                add_option(&options, NULL, parse_cmdline_module_options(argv));
+               argv[1] = NULL;
        }
 
        /* cache modules */
-       parser = config_open2("/proc/modules", fopen_for_read);
-       if (parser) {
+       {
                char *s;
+               parser_t *parser = config_open2("/proc/modules", fopen_for_read);
                while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY))
                        llist_add_to(&loaded, xstrdup(s));
                config_close(parser);
        }
 
-       for (i = 0; i < num_modules; i++) {
+       while (*argv) {
+               const char *arg = *argv;
                struct modprobe_conf *conf;
 
-               conf = xzalloc(sizeof(struct modprobe_conf));
+               conf = xzalloc(sizeof(*conf));
                conf->options = options;
-               filename2modname(argv[i], conf->probename);
+               filename2modname(arg, conf->probename);
                read_config(conf, "/etc/modprobe.conf");
                read_config(conf, "/etc/modprobe.d");
-               if (ENABLE_FEATURE_MODUTILS_SYMBOLS &&
-                   conf->aliases == NULL && strncmp(argv[i], "symbol:", 7) == 0)
+               if (ENABLE_FEATURE_MODUTILS_SYMBOLS
+                && conf->aliases == NULL
+                && strncmp(arg, "symbol:", 7) == 0
+               ) {
                        read_config(conf, "modules.symbols");
+               }
 
                if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL)
                        read_config(conf, "modules.alias");
@@ -263,11 +266,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
                if (conf->aliases == NULL) {
                        /* Try if module by literal name is found; literal
                         * names are blacklist only if '-b' is given. */
-                       if (!(option_mask32 & MODPROBE_OPT_BLACKLIST) ||
+                       if (!(opt & MODPROBE_OPT_BLACKLIST) ||
                            check_blacklist(conf, conf->probename)) {
                                rc = do_modprobe(conf, conf->probename);
-                               if (rc < 0 && !(option_mask32 & INSMOD_OPT_SILENT))
-                                       bb_error_msg("Module %s not found.", argv[i]);
+                               if (rc < 0 && !(opt & INSMOD_OPT_SILENT))
+                                       bb_error_msg("Module %s not found.", arg);
                        }
                } else {
                        /* Probe all aliases */
@@ -279,6 +282,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
                                        free(realname);
                        }
                }
+               argv++;
        }
 
        return EXIT_SUCCESS;
index 18ea5374e73d5fe8966d9011b720273feaaa10d7..10b49c901f1c667d715f52c1b200b289a8853fbc 100644 (file)
@@ -106,7 +106,7 @@ char * FAST_FUNC parse_cmdline_module_options(char **argv)
        while (*++argv) {
                options = xrealloc(options, optlen + 2 + strlen(*argv) + 2);
                /* Spaces handled by "" pairs, but no way of escaping quotes */
-               optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv);
+               optlen += sprintf(options + optlen, (strchr(*argv, ' ') ? "\"%s\" " : "%s "), *argv);
        }
        return options;
 }