From bb26db49b1b3a6cbc4b72c0cc6948432e3e77996 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 31 Oct 2008 02:04:28 +0000 Subject: [PATCH] modprobe: fix a segfault when modprobe is called with no arguments at all function old new delta modprobe_main 559 535 -24 --- modutils/modprobe.c | 52 ++++++++++++++++++++++++--------------------- modutils/modutils.c | 2 +- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 20b9a74aa..40a1e6627 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -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; diff --git a/modutils/modutils.c b/modutils/modutils.c index 18ea5374e..10b49c901 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c @@ -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; }