diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-31 02:04:28 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-31 02:04:28 +0000 |
commit | bb26db49b1b3a6cbc4b72c0cc6948432e3e77996 (patch) | |
tree | 33a7976a4b4f41839b3f4f175ac4b472daac2619 | |
parent | b9b344aa44ba6221edc8f09398325399049bf388 (diff) | |
download | busybox-w32-bb26db49b1b3a6cbc4b72c0cc6948432e3e77996.tar.gz busybox-w32-bb26db49b1b3a6cbc4b72c0cc6948432e3e77996.tar.bz2 busybox-w32-bb26db49b1b3a6cbc4b72c0cc6948432e3e77996.zip |
modprobe: fix a segfault when modprobe is called with no arguments at all
function old new delta
modprobe_main 559 535 -24
-rw-r--r-- | modutils/modprobe.c | 52 | ||||
-rw-r--r-- | 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; | |||
203 | int modprobe_main(int argc UNUSED_PARAM, char **argv) | 203 | int modprobe_main(int argc UNUSED_PARAM, char **argv) |
204 | { | 204 | { |
205 | struct utsname uts; | 205 | struct utsname uts; |
206 | int num_modules, i, rc; | 206 | int rc; |
207 | unsigned opt; | ||
207 | llist_t *options = NULL; | 208 | llist_t *options = NULL; |
208 | parser_t *parser; | ||
209 | 209 | ||
210 | opt_complementary = "q-v:v-q"; | 210 | opt_complementary = "q-v:v-q"; |
211 | getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS, | 211 | opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS, |
212 | NULL, NULL); | 212 | NULL, NULL); |
213 | argv += optind; | 213 | argv += optind; |
214 | argc -= optind; | ||
215 | 214 | ||
216 | if (option_mask32 & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY | | 215 | if (opt & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY | |
217 | MODPROBE_OPT_SHOW_ONLY)) | 216 | MODPROBE_OPT_SHOW_ONLY)) |
218 | bb_error_msg_and_die("not supported"); | 217 | bb_error_msg_and_die("not supported"); |
219 | 218 | ||
220 | /* goto modules location */ | 219 | /* goto modules location */ |
@@ -222,40 +221,44 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
222 | uname(&uts); | 221 | uname(&uts); |
223 | xchdir(uts.release); | 222 | xchdir(uts.release); |
224 | 223 | ||
225 | if (option_mask32 & (MODPROBE_OPT_REMOVE | MODPROBE_OPT_INSERT_ALL)) { | 224 | if (!argv[0]) { |
226 | /* each parameter is a module name */ | 225 | if (opt & MODPROBE_OPT_REMOVE) { |
227 | num_modules = argc; | ||
228 | if (num_modules == 0) { | ||
229 | if (bb_delete_module(NULL, O_NONBLOCK|O_EXCL) != 0) | 226 | if (bb_delete_module(NULL, O_NONBLOCK|O_EXCL) != 0) |
230 | bb_perror_msg_and_die("rmmod"); | 227 | bb_perror_msg_and_die("rmmod"); |
231 | return EXIT_SUCCESS; | ||
232 | } | 228 | } |
233 | } else { | 229 | return EXIT_SUCCESS; |
234 | /* the only module, the rest of parameters are options */ | 230 | } |
235 | num_modules = 1; | 231 | if (!(opt & MODPROBE_OPT_INSERT_ALL)) { |
232 | /* If not -a, we have only one module name, | ||
233 | * the rest of parameters are options */ | ||
236 | add_option(&options, NULL, parse_cmdline_module_options(argv)); | 234 | add_option(&options, NULL, parse_cmdline_module_options(argv)); |
235 | argv[1] = NULL; | ||
237 | } | 236 | } |
238 | 237 | ||
239 | /* cache modules */ | 238 | /* cache modules */ |
240 | parser = config_open2("/proc/modules", fopen_for_read); | 239 | { |
241 | if (parser) { | ||
242 | char *s; | 240 | char *s; |
241 | parser_t *parser = config_open2("/proc/modules", fopen_for_read); | ||
243 | while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) | 242 | while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) |
244 | llist_add_to(&loaded, xstrdup(s)); | 243 | llist_add_to(&loaded, xstrdup(s)); |
245 | config_close(parser); | 244 | config_close(parser); |
246 | } | 245 | } |
247 | 246 | ||
248 | for (i = 0; i < num_modules; i++) { | 247 | while (*argv) { |
248 | const char *arg = *argv; | ||
249 | struct modprobe_conf *conf; | 249 | struct modprobe_conf *conf; |
250 | 250 | ||
251 | conf = xzalloc(sizeof(struct modprobe_conf)); | 251 | conf = xzalloc(sizeof(*conf)); |
252 | conf->options = options; | 252 | conf->options = options; |
253 | filename2modname(argv[i], conf->probename); | 253 | filename2modname(arg, conf->probename); |
254 | read_config(conf, "/etc/modprobe.conf"); | 254 | read_config(conf, "/etc/modprobe.conf"); |
255 | read_config(conf, "/etc/modprobe.d"); | 255 | read_config(conf, "/etc/modprobe.d"); |
256 | if (ENABLE_FEATURE_MODUTILS_SYMBOLS && | 256 | if (ENABLE_FEATURE_MODUTILS_SYMBOLS |
257 | conf->aliases == NULL && strncmp(argv[i], "symbol:", 7) == 0) | 257 | && conf->aliases == NULL |
258 | && strncmp(arg, "symbol:", 7) == 0 | ||
259 | ) { | ||
258 | read_config(conf, "modules.symbols"); | 260 | read_config(conf, "modules.symbols"); |
261 | } | ||
259 | 262 | ||
260 | if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL) | 263 | if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL) |
261 | read_config(conf, "modules.alias"); | 264 | read_config(conf, "modules.alias"); |
@@ -263,11 +266,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
263 | if (conf->aliases == NULL) { | 266 | if (conf->aliases == NULL) { |
264 | /* Try if module by literal name is found; literal | 267 | /* Try if module by literal name is found; literal |
265 | * names are blacklist only if '-b' is given. */ | 268 | * names are blacklist only if '-b' is given. */ |
266 | if (!(option_mask32 & MODPROBE_OPT_BLACKLIST) || | 269 | if (!(opt & MODPROBE_OPT_BLACKLIST) || |
267 | check_blacklist(conf, conf->probename)) { | 270 | check_blacklist(conf, conf->probename)) { |
268 | rc = do_modprobe(conf, conf->probename); | 271 | rc = do_modprobe(conf, conf->probename); |
269 | if (rc < 0 && !(option_mask32 & INSMOD_OPT_SILENT)) | 272 | if (rc < 0 && !(opt & INSMOD_OPT_SILENT)) |
270 | bb_error_msg("Module %s not found.", argv[i]); | 273 | bb_error_msg("Module %s not found.", arg); |
271 | } | 274 | } |
272 | } else { | 275 | } else { |
273 | /* Probe all aliases */ | 276 | /* Probe all aliases */ |
@@ -279,6 +282,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
279 | free(realname); | 282 | free(realname); |
280 | } | 283 | } |
281 | } | 284 | } |
285 | argv++; | ||
282 | } | 286 | } |
283 | 287 | ||
284 | return EXIT_SUCCESS; | 288 | 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) | |||
106 | while (*++argv) { | 106 | while (*++argv) { |
107 | options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); | 107 | options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); |
108 | /* Spaces handled by "" pairs, but no way of escaping quotes */ | 108 | /* Spaces handled by "" pairs, but no way of escaping quotes */ |
109 | optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv); | 109 | optlen += sprintf(options + optlen, (strchr(*argv, ' ') ? "\"%s\" " : "%s "), *argv); |
110 | } | 110 | } |
111 | return options; | 111 | return options; |
112 | } | 112 | } |