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,17 +203,16 @@ 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 |
if (opt & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY |
MODPROBE_OPT_SHOW_ONLY))
bb_error_msg_and_die("not supported");
@ -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;
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;

View 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;
}