aboutsummaryrefslogtreecommitdiff
path: root/modutils/modprobe.c
diff options
context:
space:
mode:
Diffstat (limited to 'modutils/modprobe.c')
-rw-r--r--modutils/modprobe.c48
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}
232static 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 */
240static 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
237static void add_probe(const char *name) 245static 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]);