diff options
Diffstat (limited to 'modutils/modprobe.c')
-rw-r--r-- | modutils/modprobe.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index f0904285b..996de4074 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -15,8 +15,11 @@ | |||
15 | #include <sys/utsname.h> | 15 | #include <sys/utsname.h> |
16 | #include <fnmatch.h> | 16 | #include <fnmatch.h> |
17 | 17 | ||
18 | //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) | 18 | #if 1 |
19 | #define DBG(...) ((void)0) | 19 | #define DBG(...) ((void)0) |
20 | #else | ||
21 | #define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) | ||
22 | #endif | ||
20 | 23 | ||
21 | /* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t), | 24 | /* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t), |
22 | * we expect the full dependency list to be specified in modules.dep. | 25 | * we expect the full dependency list to be specified in modules.dep. |
@@ -229,26 +232,20 @@ static ALWAYS_INLINE struct module_entry *get_or_add_modentry(const char *module | |||
229 | { | 232 | { |
230 | return helper_get_module(module, 1); | 233 | return helper_get_module(module, 1); |
231 | } | 234 | } |
232 | static ALWAYS_INLINE struct module_entry *get_modentry(const char *module) | 235 | /* So far this function always gets a module pathname, never an alias name. |
236 | * The crucial difference is that pathname needs dirname stripping, | ||
237 | * while alias name must NOT do it! | ||
238 | * Testcase where dirname stripping is likely to go wrong: "modprobe devname:snd/timer" | ||
239 | */ | ||
240 | static ALWAYS_INLINE struct module_entry *get_modentry(const char *pathname) | ||
233 | { | 241 | { |
234 | return helper_get_module(module, 0); | 242 | return helper_get_module(bb_get_last_path_component_nostrip(pathname), 0); |
235 | } | 243 | } |
236 | 244 | ||
237 | static void add_probe(const char *name) | 245 | static void add_probe(const char *name) |
238 | { | 246 | { |
239 | struct module_entry *m; | 247 | struct module_entry *m; |
240 | 248 | ||
241 | /* | ||
242 | * get_or_add_modentry() strips path from name and works | ||
243 | * on remaining basename. | ||
244 | * This would make "rmmod dir/name" and "modprobe dir/name" | ||
245 | * to work like "rmmod name" and "modprobe name", | ||
246 | * which is wrong, and can be abused via implicit modprobing: | ||
247 | * "ifconfig /usbserial up" tries to modprobe netdev-/usbserial. | ||
248 | */ | ||
249 | if (strchr(name, '/')) | ||
250 | bb_error_msg_and_die("malformed module name '%s'", name); | ||
251 | |||
252 | m = get_or_add_modentry(name); | 249 | m = get_or_add_modentry(name); |
253 | if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS)) | 250 | if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS)) |
254 | && (m->flags & MODULE_FLAG_LOADED) | 251 | && (m->flags & MODULE_FLAG_LOADED) |
@@ -263,7 +260,7 @@ static void add_probe(const char *name) | |||
263 | llist_add_to_end(&G.probes, m); | 260 | llist_add_to_end(&G.probes, m); |
264 | G.num_unresolved_deps++; | 261 | G.num_unresolved_deps++; |
265 | if (ENABLE_FEATURE_MODUTILS_SYMBOLS | 262 | if (ENABLE_FEATURE_MODUTILS_SYMBOLS |
266 | && strncmp(m->modname, "symbol:", 7) == 0 | 263 | && is_prefixed_with(m->modname, "symbol:") |
267 | ) { | 264 | ) { |
268 | G.need_symbols = 1; | 265 | G.need_symbols = 1; |
269 | } | 266 | } |
@@ -356,22 +353,18 @@ static char *parse_and_add_kcmdline_module_options(char *options, const char *mo | |||
356 | char *kcmdline_buf; | 353 | char *kcmdline_buf; |
357 | char *kcmdline; | 354 | char *kcmdline; |
358 | char *kptr; | 355 | char *kptr; |
359 | int len; | ||
360 | 356 | ||
361 | kcmdline_buf = xmalloc_open_read_close("/proc/cmdline", NULL); | 357 | kcmdline_buf = xmalloc_open_read_close("/proc/cmdline", NULL); |
362 | if (!kcmdline_buf) | 358 | if (!kcmdline_buf) |
363 | return options; | 359 | return options; |
364 | 360 | ||
365 | kcmdline = kcmdline_buf; | 361 | kcmdline = kcmdline_buf; |
366 | len = strlen(modulename); | ||
367 | while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) { | 362 | while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) { |
368 | if (strncmp(modulename, kptr, len) != 0) | 363 | char *after_modulename = is_prefixed_with(kptr, modulename); |
369 | continue; | 364 | if (!after_modulename || *after_modulename != '.') |
370 | kptr += len; | ||
371 | if (*kptr != '.') | ||
372 | continue; | 365 | continue; |
373 | /* It is "modulename.xxxx" */ | 366 | /* It is "modulename.xxxx" */ |
374 | kptr++; | 367 | kptr = after_modulename + 1; |
375 | if (strchr(kptr, '=') != NULL) { | 368 | if (strchr(kptr, '=') != NULL) { |
376 | /* It is "modulename.opt=[val]" */ | 369 | /* It is "modulename.opt=[val]" */ |
377 | options = gather_options_str(options, kptr); | 370 | options = gather_options_str(options, kptr); |
@@ -428,7 +421,7 @@ static int do_modprobe(struct module_entry *m) | |||
428 | 421 | ||
429 | rc = 0; | 422 | rc = 0; |
430 | fn = llist_pop(&m->deps); /* we leak it */ | 423 | fn = llist_pop(&m->deps); /* we leak it */ |
431 | m2 = get_or_add_modentry(fn); | 424 | m2 = get_or_add_modentry(bb_get_last_path_component_nostrip(fn)); |
432 | 425 | ||
433 | if (option_mask32 & OPT_REMOVE) { | 426 | if (option_mask32 & OPT_REMOVE) { |
434 | /* modprobe -r */ | 427 | /* modprobe -r */ |
@@ -510,7 +503,7 @@ static void load_modules_dep(void) | |||
510 | colon = last_char_is(tokens[0], ':'); | 503 | colon = last_char_is(tokens[0], ':'); |
511 | if (colon == NULL) | 504 | if (colon == NULL) |
512 | continue; | 505 | continue; |
513 | *colon = 0; | 506 | *colon = '\0'; |
514 | 507 | ||
515 | m = get_modentry(tokens[0]); | 508 | m = get_modentry(tokens[0]); |
516 | if (m == NULL) | 509 | if (m == NULL) |
@@ -557,7 +550,6 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
557 | 550 | ||
558 | if (opt & OPT_LIST_ONLY) { | 551 | if (opt & OPT_LIST_ONLY) { |
559 | int i; | 552 | int i; |
560 | char name[MODULE_NAME_LEN]; | ||
561 | char *colon, *tokens[2]; | 553 | char *colon, *tokens[2]; |
562 | parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read); | 554 | parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read); |
563 | 555 | ||
@@ -569,10 +561,14 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
569 | if (!colon) | 561 | if (!colon) |
570 | continue; | 562 | continue; |
571 | *colon = '\0'; | 563 | *colon = '\0'; |
572 | filename2modname(tokens[0], name); | ||
573 | if (!argv[0]) | 564 | if (!argv[0]) |
574 | puts(tokens[0]); | 565 | puts(tokens[0]); |
575 | else { | 566 | else { |
567 | char name[MODULE_NAME_LEN]; | ||
568 | filename2modname( | ||
569 | bb_get_last_path_component_nostrip(tokens[0]), | ||
570 | name | ||
571 | ); | ||
576 | for (i = 0; argv[i]; i++) { | 572 | for (i = 0; argv[i]; i++) { |
577 | if (fnmatch(argv[i], name, 0) == 0) { | 573 | if (fnmatch(argv[i], name, 0) == 0) { |
578 | puts(tokens[0]); | 574 | puts(tokens[0]); |