modprobe: fix a segfault when modprobe is called with no arguments at all

function                                             old     new   delta
modprobe_main                                        559     535     -24
This commit is contained in:
Denis Vlasenko 2008-10-31 02:04:28 +00:00
parent b9b344aa44
commit bb26db49b1
2 changed files with 29 additions and 25 deletions

View File

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

View File

@ -106,7 +106,7 @@ char * FAST_FUNC parse_cmdline_module_options(char **argv)
while (*++argv) { while (*++argv) {
options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); options = xrealloc(options, optlen + 2 + strlen(*argv) + 2);
/* Spaces handled by "" pairs, but no way of escaping quotes */ /* 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; return options;
} }