aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbb/xreadlink.c3
-rw-r--r--modutils/insmod.c411
-rw-r--r--modutils/lsmod.c10
-rw-r--r--modutils/modprobe.c270
4 files changed, 313 insertions, 381 deletions
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index 4d87b944d..98b795f56 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -18,7 +18,8 @@ char *xmalloc_readlink(const char *path)
18 int bufsize = 0, readsize = 0; 18 int bufsize = 0, readsize = 0;
19 19
20 do { 20 do {
21 buf = xrealloc(buf, bufsize += GROWBY); 21 bufsize += GROWBY;
22 buf = xrealloc(buf, bufsize);
22 readsize = readlink(path, buf, bufsize); 23 readsize = readlink(path, buf, bufsize);
23 if (readsize == -1) { 24 if (readsize == -1) {
24 free(buf); 25 free(buf);
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 6f3b7d0f4..df75abbfa 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -67,25 +67,21 @@
67#define ENABLE_FEATURE_2_4_MODULES 1 67#define ENABLE_FEATURE_2_4_MODULES 1
68#endif 68#endif
69 69
70#if !ENABLE_FEATURE_2_4_MODULES 70/*
71#define insmod_ng_main insmod_main 71 * Big piece of 2.4-specific code
72#endif 72 */
73#if ENABLE_FEATURE_2_4_MODULES
73 74
74#if ENABLE_FEATURE_2_6_MODULES 75#if ENABLE_FEATURE_2_6_MODULES
75extern int insmod_ng_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 76static int insmod_ng_main(int argc, char **argv);
76#endif 77#endif
77 78
78
79#if ENABLE_FEATURE_2_4_MODULES
80
81
82#if ENABLE_FEATURE_INSMOD_LOADINKMEM 79#if ENABLE_FEATURE_INSMOD_LOADINKMEM
83#define LOADBITS 0 80#define LOADBITS 0
84#else 81#else
85#define LOADBITS 1 82#define LOADBITS 1
86#endif 83#endif
87 84
88
89/* Alpha */ 85/* Alpha */
90#if defined(__alpha__) 86#if defined(__alpha__)
91#define MATCH_MACHINE(x) (x == EM_ALPHA) 87#define MATCH_MACHINE(x) (x == EM_ALPHA)
@@ -627,13 +623,13 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
627 623
628static void *obj_extend_section(struct obj_section *sec, unsigned long more); 624static void *obj_extend_section(struct obj_section *sec, unsigned long more);
629 625
630static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 626static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
631 const char *string); 627 const char *string);
632 628
633static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 629static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
634 struct obj_symbol *sym); 630 struct obj_symbol *sym);
635 631
636static int obj_check_undefineds(struct obj_file *f); 632static void obj_check_undefineds(struct obj_file *f);
637 633
638static void obj_allocate_commons(struct obj_file *f); 634static void obj_allocate_commons(struct obj_file *f);
639 635
@@ -788,7 +784,6 @@ static size_t nksyms;
788static struct external_module *ext_modules; 784static struct external_module *ext_modules;
789static int n_ext_modules; 785static int n_ext_modules;
790static int n_ext_modules_used; 786static int n_ext_modules_used;
791extern int delete_module(const char *);
792 787
793static char *m_filename; 788static char *m_filename;
794static char *m_fullName; 789static char *m_fullName;
@@ -801,19 +796,16 @@ static int check_module_name_match(const char *filename, struct stat *statbuf,
801 void *userdata, int depth) 796 void *userdata, int depth)
802{ 797{
803 char *fullname = (char *) userdata; 798 char *fullname = (char *) userdata;
799 char *tmp;
804 800
805 if (fullname[0] == '\0') 801 if (fullname[0] == '\0')
806 return FALSE; 802 return FALSE;
807 else { 803
808 char *tmp, *tmp1 = xstrdup(filename); 804 tmp = bb_get_last_path_component_nostrip(filename);
809 tmp = bb_get_last_path_component_nostrip(tmp1); 805 if (strcmp(tmp, fullname) == 0) {
810 if (strcmp(tmp, fullname) == 0) { 806 /* Stop searching if we find a match */
811 free(tmp1); 807 m_filename = xstrdup(filename);
812 /* Stop searching if we find a match */ 808 return FALSE;
813 m_filename = xstrdup(filename);
814 return FALSE;
815 }
816 free(tmp1);
817 } 809 }
818 return TRUE; 810 return TRUE;
819} 811}
@@ -824,25 +816,19 @@ static int check_module_name_match(const char *filename, struct stat *statbuf,
824static struct obj_file *arch_new_file(void) 816static struct obj_file *arch_new_file(void)
825{ 817{
826 struct arch_file *f; 818 struct arch_file *f;
827 f = xmalloc(sizeof(*f)); 819 f = xzalloc(sizeof(*f));
828 820 return &f->root; /* it's a first member */
829 memset(f, 0, sizeof(*f));
830
831 return &f->root;
832} 821}
833 822
834static struct obj_section *arch_new_section(void) 823static struct obj_section *arch_new_section(void)
835{ 824{
836 return xmalloc(sizeof(struct obj_section)); 825 return xzalloc(sizeof(struct obj_section));
837} 826}
838 827
839static struct obj_symbol *arch_new_symbol(void) 828static struct obj_symbol *arch_new_symbol(void)
840{ 829{
841 struct arch_symbol *sym; 830 struct arch_symbol *sym;
842 sym = xmalloc(sizeof(*sym)); 831 sym = xzalloc(sizeof(*sym));
843
844 memset(sym, 0, sizeof(*sym));
845
846 return &sym->root; 832 return &sym->root;
847} 833}
848 834
@@ -2210,7 +2196,6 @@ static struct obj_section *obj_create_alloced_section(struct obj_file *f,
2210 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); 2196 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2211 f->sections[newidx] = sec = arch_new_section(); 2197 f->sections[newidx] = sec = arch_new_section();
2212 2198
2213 memset(sec, 0, sizeof(*sec));
2214 sec->header.sh_type = SHT_PROGBITS; 2199 sec->header.sh_type = SHT_PROGBITS;
2215 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 2200 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2216 sec->header.sh_size = size; 2201 sec->header.sh_size = size;
@@ -2236,7 +2221,6 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2236 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); 2221 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2237 f->sections[newidx] = sec = arch_new_section(); 2222 f->sections[newidx] = sec = arch_new_section();
2238 2223
2239 memset(sec, 0, sizeof(*sec));
2240 sec->header.sh_type = SHT_PROGBITS; 2224 sec->header.sh_type = SHT_PROGBITS;
2241 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 2225 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2242 sec->header.sh_size = size; 2226 sec->header.sh_size = size;
@@ -2398,7 +2382,7 @@ static char *get_modinfo_value(struct obj_file *f, const char *key)
2398/*======================================================================*/ 2382/*======================================================================*/
2399/* Functions relating to module loading after 2.1.18. */ 2383/* Functions relating to module loading after 2.1.18. */
2400 2384
2401static int 2385static void
2402new_process_module_arguments(struct obj_file *f, int argc, char **argv) 2386new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2403{ 2387{
2404 while (argc > 0) { 2388 while (argc > 0) {
@@ -2408,7 +2392,8 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2408 int min, max, n; 2392 int min, max, n;
2409 2393
2410 p = *argv; 2394 p = *argv;
2411 if ((q = strchr(p, '=')) == NULL) { 2395 q = strchr(p, '=');
2396 if (q == NULL) {
2412 argc--; 2397 argc--;
2413 continue; 2398 continue;
2414 } 2399 }
@@ -2421,8 +2406,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2421 p = get_modinfo_value(f, key); 2406 p = get_modinfo_value(f, key);
2422 key += 5; 2407 key += 5;
2423 if (p == NULL) { 2408 if (p == NULL) {
2424 bb_error_msg("invalid parameter %s", key); 2409 bb_error_msg_and_die("invalid parameter %s", key);
2425 return 0;
2426 } 2410 }
2427 2411
2428#ifdef SYMBOL_PREFIX 2412#ifdef SYMBOL_PREFIX
@@ -2436,8 +2420,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2436 2420
2437 /* Also check that the parameter was not resolved from the kernel. */ 2421 /* Also check that the parameter was not resolved from the kernel. */
2438 if (sym == NULL || sym->secidx > SHN_HIRESERVE) { 2422 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
2439 bb_error_msg("symbol for parameter %s not found", key); 2423 bb_error_msg_and_die("symbol for parameter %s not found", key);
2440 return 0;
2441 } 2424 }
2442 2425
2443 if (isdigit(*p)) { 2426 if (isdigit(*p)) {
@@ -2463,11 +2446,10 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2463 2446
2464 str = alloca(strlen(q)); 2447 str = alloca(strlen(q));
2465 for (r = str, q++; *q != '"'; ++q, ++r) { 2448 for (r = str, q++; *q != '"'; ++q, ++r) {
2466 if (*q == '\0') { 2449 if (*q == '\0')
2467 bb_error_msg("improperly terminated string argument for %s", 2450 bb_error_msg_and_die("improperly terminated string argument for %s",
2468 key); 2451 key);
2469 return 0; 2452 if (*q == '\\')
2470 } else if (*q == '\\')
2471 switch (*++q) { 2453 switch (*++q) {
2472 case 'a': 2454 case 'a':
2473 *r = '\a'; 2455 *r = '\a';
@@ -2513,8 +2495,9 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2513 default: 2495 default:
2514 *r = *q; 2496 *r = *q;
2515 break; 2497 break;
2516 } else 2498 }
2517 *r = *q; 2499 else
2500 *r = *q;
2518 } 2501 }
2519 *r = '\0'; 2502 *r = '\0';
2520 ++q; 2503 ++q;
@@ -2558,17 +2541,15 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2558 /* Get the size of each member */ 2541 /* Get the size of each member */
2559 /* Probably we should do that outside the loop ? */ 2542 /* Probably we should do that outside the loop ? */
2560 if (!isdigit(*(p + 1))) { 2543 if (!isdigit(*(p + 1))) {
2561 bb_error_msg("parameter type 'c' for %s must be followed by" 2544 bb_error_msg_and_die("parameter type 'c' for %s must be followed by"
2562 " the maximum size", key); 2545 " the maximum size", key);
2563 return 0;
2564 } 2546 }
2565 charssize = strtoul(p + 1, (char **) NULL, 10); 2547 charssize = strtoul(p + 1, (char **) NULL, 10);
2566 2548
2567 /* Check length */ 2549 /* Check length */
2568 if (strlen(str) >= charssize) { 2550 if (strlen(str) >= charssize) {
2569 bb_error_msg("string too long for %s (max %ld)", key, 2551 bb_error_msg_and_die("string too long for %s (max %ld)", key,
2570 charssize - 1); 2552 charssize - 1);
2571 return 0;
2572 } 2553 }
2573 2554
2574 /* Copy to location */ 2555 /* Copy to location */
@@ -2595,12 +2576,10 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2595 break; 2576 break;
2596 2577
2597 default: 2578 default:
2598 bb_error_msg("unknown parameter type '%c' for %s", *p, key); 2579 bb_error_msg_and_die("unknown parameter type '%c' for %s", *p, key);
2599 return 0;
2600 } 2580 }
2601 } 2581 }
2602 2582 retry_end_of_value:
2603retry_end_of_value:
2604 switch (*q) { 2583 switch (*q) {
2605 case '\0': 2584 case '\0':
2606 goto end_of_arg; 2585 goto end_of_arg;
@@ -2614,28 +2593,23 @@ retry_end_of_value:
2614 2593
2615 case ',': 2594 case ',':
2616 if (++n > max) { 2595 if (++n > max) {
2617 bb_error_msg("too many values for %s (max %d)", key, max); 2596 bb_error_msg_and_die("too many values for %s (max %d)", key, max);
2618 return 0;
2619 } 2597 }
2620 ++q; 2598 ++q;
2621 break; 2599 break;
2622 2600
2623 default: 2601 default:
2624 bb_error_msg("invalid argument syntax for %s", key); 2602 bb_error_msg_and_die("invalid argument syntax for %s", key);
2625 return 0;
2626 } 2603 }
2627 } 2604 }
2628 2605 end_of_arg:
2629end_of_arg:
2630 if (n < min) { 2606 if (n < min) {
2631 bb_error_msg("too few values for %s (min %d)", key, min); 2607 bb_error_msg_and_die("too few values for %s (min %d)", key, min);
2632 return 0;
2633 } 2608 }
2634 2609
2635 argc--, argv++; 2610 argc--;
2611 argv++;
2636 } 2612 }
2637
2638 return 1;
2639} 2613}
2640 2614
2641#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 2615#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
@@ -2644,8 +2618,7 @@ static int new_is_module_checksummed(struct obj_file *f)
2644 const char *p = get_modinfo_value(f, "using_checksums"); 2618 const char *p = get_modinfo_value(f, "using_checksums");
2645 if (p) 2619 if (p)
2646 return xatoi(p); 2620 return xatoi(p);
2647 else 2621 return 0;
2648 return 0;
2649} 2622}
2650 2623
2651/* Get the module's kernel version in the canonical integer form. */ 2624/* Get the module's kernel version in the canonical integer form. */
@@ -2679,7 +2652,7 @@ new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2679 2652
2680/* Fetch the loaded modules, and all currently exported symbols. */ 2653/* Fetch the loaded modules, and all currently exported symbols. */
2681 2654
2682static int new_get_kernel_symbols(void) 2655static void new_get_kernel_symbols(void)
2683{ 2656{
2684 char *module_names, *mn; 2657 char *module_names, *mn;
2685 struct external_module *modules, *m; 2658 struct external_module *modules, *m;
@@ -2688,15 +2661,17 @@ static int new_get_kernel_symbols(void)
2688 2661
2689 /* Collect the loaded modules. */ 2662 /* Collect the loaded modules. */
2690 2663
2691 module_names = xmalloc(bufsize = 256); 2664 bufsize = 256;
2692retry_modules_load: 2665 module_names = xmalloc(bufsize);
2666
2667 retry_modules_load:
2693 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { 2668 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2694 if (errno == ENOSPC && bufsize < ret) { 2669 if (errno == ENOSPC && bufsize < ret) {
2695 module_names = xrealloc(module_names, bufsize = ret); 2670 bufsize = ret;
2671 module_names = xrealloc(module_names, bufsize);
2696 goto retry_modules_load; 2672 goto retry_modules_load;
2697 } 2673 }
2698 bb_perror_msg("QM_MODULES"); 2674 bb_perror_msg_and_die("QM_MODULES");
2699 return 0;
2700 } 2675 }
2701 2676
2702 n_ext_modules = nmod = ret; 2677 n_ext_modules = nmod = ret;
@@ -2715,23 +2690,23 @@ retry_modules_load:
2715 /* The module was removed out from underneath us. */ 2690 /* The module was removed out from underneath us. */
2716 continue; 2691 continue;
2717 } 2692 }
2718 bb_perror_msg("query_module: QM_INFO: %s", mn); 2693 bb_perror_msg_and_die("query_module: QM_INFO: %s", mn);
2719 return 0;
2720 } 2694 }
2721 2695
2722 syms = xmalloc(bufsize = 1024); 2696 bufsize = 1024;
2723retry_mod_sym_load: 2697 syms = xmalloc(bufsize);
2698 retry_mod_sym_load:
2724 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { 2699 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2725 switch (errno) { 2700 switch (errno) {
2726 case ENOSPC: 2701 case ENOSPC:
2727 syms = xrealloc(syms, bufsize = ret); 2702 bufsize = ret;
2703 syms = xrealloc(syms, bufsize);
2728 goto retry_mod_sym_load; 2704 goto retry_mod_sym_load;
2729 case ENOENT: 2705 case ENOENT:
2730 /* The module was removed out from underneath us. */ 2706 /* The module was removed out from underneath us. */
2731 continue; 2707 continue;
2732 default: 2708 default:
2733 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn); 2709 bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn);
2734 return 0;
2735 } 2710 }
2736 } 2711 }
2737 nsyms = ret; 2712 nsyms = ret;
@@ -2750,14 +2725,13 @@ retry_mod_sym_load:
2750 /* Collect the kernel's symbols. */ 2725 /* Collect the kernel's symbols. */
2751 2726
2752 syms = xmalloc(bufsize = 16 * 1024); 2727 syms = xmalloc(bufsize = 16 * 1024);
2753retry_kern_sym_load: 2728 retry_kern_sym_load:
2754 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { 2729 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2755 if (errno == ENOSPC && bufsize < ret) { 2730 if (errno == ENOSPC && bufsize < ret) {
2756 syms = xrealloc(syms, bufsize = ret); 2731 syms = xrealloc(syms, bufsize = ret);
2757 goto retry_kern_sym_load; 2732 goto retry_kern_sym_load;
2758 } 2733 }
2759 bb_perror_msg("kernel: QM_SYMBOLS"); 2734 bb_perror_msg_and_die("kernel: QM_SYMBOLS");
2760 return 0;
2761 } 2735 }
2762 nksyms = nsyms = ret; 2736 nksyms = nsyms = ret;
2763 ksyms = syms; 2737 ksyms = syms;
@@ -2765,7 +2739,6 @@ retry_kern_sym_load:
2765 for (j = 0, s = syms; j < nsyms; ++j, ++s) { 2739 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2766 s->name += (unsigned long) syms; 2740 s->name += (unsigned long) syms;
2767 } 2741 }
2768 return 1;
2769} 2742}
2770 2743
2771 2744
@@ -2786,7 +2759,7 @@ static int new_is_kernel_checksummed(void)
2786} 2759}
2787 2760
2788 2761
2789static int new_create_this_module(struct obj_file *f, const char *m_name) 2762static void new_create_this_module(struct obj_file *f, const char *m_name)
2790{ 2763{
2791 struct obj_section *sec; 2764 struct obj_section *sec;
2792 2765
@@ -2800,8 +2773,6 @@ static int new_create_this_module(struct obj_file *f, const char *m_name)
2800 2773
2801 obj_string_patch(f, sec->idx, offsetof(struct new_module, name), 2774 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2802 m_name); 2775 m_name);
2803
2804 return 1;
2805} 2776}
2806 2777
2807#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 2778#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
@@ -2985,7 +2956,7 @@ new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2985 2956
2986/*======================================================================*/ 2957/*======================================================================*/
2987 2958
2988static int 2959static void
2989obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 2960obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2990 const char *string) 2961 const char *string)
2991{ 2962{
@@ -3010,11 +2981,9 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3010 loc = obj_extend_section(strsec, len); 2981 loc = obj_extend_section(strsec, len);
3011 } 2982 }
3012 memcpy(loc, string, len); 2983 memcpy(loc, string, len);
3013
3014 return 1;
3015} 2984}
3016 2985
3017static int 2986static void
3018obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 2987obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3019 struct obj_symbol *sym) 2988 struct obj_symbol *sym)
3020{ 2989{
@@ -3026,14 +2995,11 @@ obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3026 p->reloc_offset = offset; 2995 p->reloc_offset = offset;
3027 p->sym = sym; 2996 p->sym = sym;
3028 f->symbol_patches = p; 2997 f->symbol_patches = p;
3029
3030 return 1;
3031} 2998}
3032 2999
3033static int obj_check_undefineds(struct obj_file *f) 3000static void obj_check_undefineds(struct obj_file *f)
3034{ 3001{
3035 unsigned long i; 3002 unsigned i;
3036 int ret = 1;
3037 3003
3038 for (i = 0; i < HASH_BUCKETS; ++i) { 3004 for (i = 0; i < HASH_BUCKETS; ++i) {
3039 struct obj_symbol *sym; 3005 struct obj_symbol *sym;
@@ -3043,15 +3009,11 @@ static int obj_check_undefineds(struct obj_file *f)
3043 sym->secidx = SHN_ABS; 3009 sym->secidx = SHN_ABS;
3044 sym->value = 0; 3010 sym->value = 0;
3045 } else { 3011 } else {
3046 if (!flag_quiet) { 3012 if (!flag_quiet)
3047 bb_error_msg("unresolved symbol %s", sym->name); 3013 bb_error_msg_and_die("unresolved symbol %s", sym->name);
3048 }
3049 ret = 0;
3050 } 3014 }
3051 } 3015 }
3052 } 3016 }
3053
3054 return ret;
3055} 3017}
3056 3018
3057static void obj_allocate_commons(struct obj_file *f) 3019static void obj_allocate_commons(struct obj_file *f)
@@ -3114,7 +3076,6 @@ static void obj_allocate_commons(struct obj_file *f)
3114 f->sections[i] = sec = arch_new_section(); 3076 f->sections[i] = sec = arch_new_section();
3115 f->header.e_shnum = i + 1; 3077 f->header.e_shnum = i + 1;
3116 3078
3117 memset(sec, 0, sizeof(*sec));
3118 sec->header.sh_type = SHT_PROGBITS; 3079 sec->header.sh_type = SHT_PROGBITS;
3119 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 3080 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
3120 sec->name = ".bss"; 3081 sec->name = ".bss";
@@ -3347,44 +3308,38 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3347 /* Read the file header. */ 3308 /* Read the file header. */
3348 3309
3349 f = arch_new_file(); 3310 f = arch_new_file();
3350 memset(f, 0, sizeof(*f));
3351 f->symbol_cmp = strcmp; 3311 f->symbol_cmp = strcmp;
3352 f->symbol_hash = obj_elf_hash; 3312 f->symbol_hash = obj_elf_hash;
3353 f->load_order_search_start = &f->load_order; 3313 f->load_order_search_start = &f->load_order;
3354 3314
3355 fseek(fp, 0, SEEK_SET); 3315 fseek(fp, 0, SEEK_SET);
3356 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) { 3316 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
3357 bb_perror_msg("error reading ELF header"); 3317 bb_perror_msg_and_die("error reading ELF header");
3358 return NULL;
3359 } 3318 }
3360 3319
3361 if (f->header.e_ident[EI_MAG0] != ELFMAG0 3320 if (f->header.e_ident[EI_MAG0] != ELFMAG0
3362 || f->header.e_ident[EI_MAG1] != ELFMAG1 3321 || f->header.e_ident[EI_MAG1] != ELFMAG1
3363 || f->header.e_ident[EI_MAG2] != ELFMAG2 3322 || f->header.e_ident[EI_MAG2] != ELFMAG2
3364 || f->header.e_ident[EI_MAG3] != ELFMAG3) { 3323 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
3365 bb_error_msg("not an ELF file"); 3324 bb_error_msg_and_die("not an ELF file");
3366 return NULL;
3367 } 3325 }
3368 if (f->header.e_ident[EI_CLASS] != ELFCLASSM 3326 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
3369 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN 3327 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN
3370 ? ELFDATA2MSB : ELFDATA2LSB) 3328 ? ELFDATA2MSB : ELFDATA2LSB)
3371 || f->header.e_ident[EI_VERSION] != EV_CURRENT 3329 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3372 || !MATCH_MACHINE(f->header.e_machine)) { 3330 || !MATCH_MACHINE(f->header.e_machine)) {
3373 bb_error_msg("ELF file not for this architecture"); 3331 bb_error_msg_and_die("ELF file not for this architecture");
3374 return NULL;
3375 } 3332 }
3376 if (f->header.e_type != ET_REL) { 3333 if (f->header.e_type != ET_REL) {
3377 bb_error_msg("ELF file not a relocatable object"); 3334 bb_error_msg_and_die("ELF file not a relocatable object");
3378 return NULL;
3379 } 3335 }
3380 3336
3381 /* Read the section headers. */ 3337 /* Read the section headers. */
3382 3338
3383 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) { 3339 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3384 bb_error_msg("section header size mismatch: %lu != %lu", 3340 bb_error_msg_and_die("section header size mismatch: %lu != %lu",
3385 (unsigned long) f->header.e_shentsize, 3341 (unsigned long) f->header.e_shentsize,
3386 (unsigned long) sizeof(ElfW(Shdr))); 3342 (unsigned long) sizeof(ElfW(Shdr)));
3387 return NULL;
3388 } 3343 }
3389 3344
3390 shnum = f->header.e_shnum; 3345 shnum = f->header.e_shnum;
@@ -3394,8 +3349,7 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3394 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); 3349 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3395 fseek(fp, f->header.e_shoff, SEEK_SET); 3350 fseek(fp, f->header.e_shoff, SEEK_SET);
3396 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) { 3351 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
3397 bb_perror_msg("error reading ELF section headers"); 3352 bb_perror_msg_and_die("error reading ELF section headers");
3398 return NULL;
3399 } 3353 }
3400 3354
3401 /* Read the section data. */ 3355 /* Read the section data. */
@@ -3404,7 +3358,6 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3404 struct obj_section *sec; 3358 struct obj_section *sec;
3405 3359
3406 f->sections[i] = sec = arch_new_section(); 3360 f->sections[i] = sec = arch_new_section();
3407 memset(sec, 0, sizeof(*sec));
3408 3361
3409 sec->header = section_headers[i]; 3362 sec->header = section_headers[i];
3410 sec->idx = i; 3363 sec->idx = i;
@@ -3431,8 +3384,7 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3431 sec->contents = xmalloc(sec->header.sh_size); 3384 sec->contents = xmalloc(sec->header.sh_size);
3432 fseek(fp, sec->header.sh_offset, SEEK_SET); 3385 fseek(fp, sec->header.sh_offset, SEEK_SET);
3433 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { 3386 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3434 bb_perror_msg("error reading ELF section data"); 3387 bb_perror_msg_and_die("error reading ELF section data");
3435 return NULL;
3436 } 3388 }
3437 } else { 3389 } else {
3438 sec->contents = NULL; 3390 sec->contents = NULL;
@@ -3441,14 +3393,11 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3441 3393
3442#if SHT_RELM == SHT_REL 3394#if SHT_RELM == SHT_REL
3443 case SHT_RELA: 3395 case SHT_RELA:
3444 bb_error_msg("RELA relocations not supported on this architecture"); 3396 bb_error_msg_and_die("RELA relocations not supported on this architecture");
3445 return NULL;
3446#else 3397#else
3447 case SHT_REL: 3398 case SHT_REL:
3448 bb_error_msg("REL relocations not supported on this architecture"); 3399 bb_error_msg_and_die("REL relocations not supported on this architecture");
3449 return NULL;
3450#endif 3400#endif
3451
3452 default: 3401 default:
3453 if (sec->header.sh_type >= SHT_LOPROC) { 3402 if (sec->header.sh_type >= SHT_LOPROC) {
3454 /* Assume processor specific section types are debug 3403 /* Assume processor specific section types are debug
@@ -3458,9 +3407,8 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3458 break; 3407 break;
3459 } 3408 }
3460 3409
3461 bb_error_msg("can't handle sections of type %ld", 3410 bb_error_msg_and_die("can't handle sections of type %ld",
3462 (long) sec->header.sh_type); 3411 (long) sec->header.sh_type);
3463 return NULL;
3464 } 3412 }
3465 } 3413 }
3466 } 3414 }
@@ -3494,10 +3442,9 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3494 ElfW(Sym) * sym; 3442 ElfW(Sym) * sym;
3495 3443
3496 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { 3444 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3497 bb_error_msg("symbol size mismatch: %lu != %lu", 3445 bb_error_msg_and_die("symbol size mismatch: %lu != %lu",
3498 (unsigned long) sec->header.sh_entsize, 3446 (unsigned long) sec->header.sh_entsize,
3499 (unsigned long) sizeof(ElfW(Sym))); 3447 (unsigned long) sizeof(ElfW(Sym)));
3500 return NULL;
3501 } 3448 }
3502 3449
3503 nsym = sec->header.sh_size / sizeof(ElfW(Sym)); 3450 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
@@ -3528,7 +3475,6 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3528 */ 3475 */
3529 val |= sym->st_other & 4; 3476 val |= sym->st_other & 4;
3530#endif 3477#endif
3531
3532 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, 3478 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3533 val, sym->st_size); 3479 val, sym->st_size);
3534 } 3480 }
@@ -3537,10 +3483,9 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3537 3483
3538 case SHT_RELM: 3484 case SHT_RELM:
3539 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { 3485 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3540 bb_error_msg("relocation entry size mismatch: %lu != %lu", 3486 bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu",
3541 (unsigned long) sec->header.sh_entsize, 3487 (unsigned long) sec->header.sh_entsize,
3542 (unsigned long) sizeof(ElfW(RelM))); 3488 (unsigned long) sizeof(ElfW(RelM)));
3543 return NULL;
3544 } 3489 }
3545 break; 3490 break;
3546 /* XXX Relocation code from modutils-2.3.19 is not here. 3491 /* XXX Relocation code from modutils-2.3.19 is not here.
@@ -3638,8 +3583,9 @@ static int obj_gpl_license(struct obj_file *f, const char **license)
3638 } 3583 }
3639 return 2; 3584 return 2;
3640 } 3585 }
3641 if (strchr(ptr, '\0')) 3586 ptr = strchr(ptr, '\0');
3642 ptr = strchr(ptr, '\0') + 1; 3587 if (ptr)
3588 ptr++;
3643 else 3589 else
3644 ptr = endptr; 3590 ptr = endptr;
3645 } 3591 }
@@ -3648,12 +3594,12 @@ static int obj_gpl_license(struct obj_file *f, const char **license)
3648} 3594}
3649 3595
3650#define TAINT_FILENAME "/proc/sys/kernel/tainted" 3596#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3651#define TAINT_PROPRIETORY_MODULE (1<<0) 3597#define TAINT_PROPRIETORY_MODULE (1 << 0)
3652#define TAINT_FORCED_MODULE (1<<1) 3598#define TAINT_FORCED_MODULE (1 << 1)
3653#define TAINT_UNSAFE_SMP (1<<2) 3599#define TAINT_UNSAFE_SMP (1 << 2)
3654#define TAINT_URL "http://www.tux.org/lkml/#export-tainted" 3600#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3655 3601
3656static void set_tainted(struct obj_file *f, int fd, char *m_name, 3602static void set_tainted(int fd, char *m_name,
3657 int kernel_has_tainted, int taint, const char *text1, const char *text2) 3603 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3658{ 3604{
3659 static smallint printed_info; 3605 static smallint printed_info;
@@ -3703,22 +3649,22 @@ static void check_tainted_module(struct obj_file *f, char *m_name)
3703 case 0: 3649 case 0:
3704 break; 3650 break;
3705 case 1: 3651 case 1:
3706 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", ""); 3652 set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3707 break; 3653 break;
3708 case 2: 3654 case 2:
3709 /* The module has a non-GPL license so we pretend that the 3655 /* The module has a non-GPL license so we pretend that the
3710 * kernel always has a taint flag to get a warning even on 3656 * kernel always has a taint flag to get a warning even on
3711 * kernels without the proc flag. 3657 * kernels without the proc flag.
3712 */ 3658 */
3713 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); 3659 set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3714 break; 3660 break;
3715 default: 3661 default:
3716 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); 3662 set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3717 break; 3663 break;
3718 } 3664 }
3719 3665
3720 if (flag_force_load) 3666 if (flag_force_load)
3721 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", ""); 3667 set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3722 3668
3723 if (fd >= 0) 3669 if (fd >= 0)
3724 close(fd); 3670 close(fd);
@@ -3752,15 +3698,7 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
3752 const char *m_name) 3698 const char *m_name)
3753{ 3699{
3754 static const char symprefix[] ALIGN1 = "__insmod_"; 3700 static const char symprefix[] ALIGN1 = "__insmod_";
3755 3701 static const char section_names[][8] = {
3756 struct obj_section *sec;
3757 struct obj_symbol *sym;
3758 char *name, *absolute_filename;
3759 char str[STRVERSIONLEN], real[PATH_MAX];
3760 int i, l, lm_name, lfilename, use_ksymtab, version;
3761 struct stat statbuf;
3762
3763 static const char *section_names[] = {
3764 ".text", 3702 ".text",
3765 ".rodata", 3703 ".rodata",
3766 ".data", 3704 ".data",
@@ -3768,12 +3706,18 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
3768 ".sbss" 3706 ".sbss"
3769 }; 3707 };
3770 3708
3771 if (realpath(filename, real)) { 3709 struct obj_section *sec;
3772 absolute_filename = xstrdup(real); 3710 struct obj_symbol *sym;
3773 } else { 3711 char *name, *absolute_filename;
3774 bb_perror_msg("cannot get realpath for %s", filename); 3712 char str[STRVERSIONLEN];
3713 int i, l, lm_name, lfilename, use_ksymtab, version;
3714 struct stat statbuf;
3715
3716 /* WARNING: was using realpath, but replaced by readlink to stop using
3717 * lots of stack. But here it seems to be able to cause problems? */
3718 absolute_filename = xmalloc_readlink(filename);
3719 if (!absolute_filename)
3775 absolute_filename = xstrdup(filename); 3720 absolute_filename = xstrdup(filename);
3776 }
3777 3721
3778 lm_name = strlen(m_name); 3722 lm_name = strlen(m_name);
3779 lfilename = strlen(absolute_filename); 3723 lfilename = strlen(absolute_filename);
@@ -3791,22 +3735,22 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
3791 * is 0xffffff, decimal 16777215. putting all three fields in 3735 * is 0xffffff, decimal 16777215. putting all three fields in
3792 * one symbol is less readable but saves kernel space. 3736 * one symbol is less readable but saves kernel space.
3793 */ 3737 */
3794 l = sizeof(symprefix)+ /* "__insmod_" */ 3738 l = sizeof(symprefix) + /* "__insmod_" */
3795 lm_name+ /* module name */ 3739 lm_name + /* module name */
3796 2+ /* "_O" */ 3740 2 + /* "_O" */
3797 lfilename+ /* object filename */ 3741 lfilename + /* object filename */
3798 2+ /* "_M" */ 3742 2 + /* "_M" */
3799 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ 3743 2 * sizeof(statbuf.st_mtime) + /* mtime in hex */
3800 2+ /* "_V" */ 3744 2 + /* "_V" */
3801 8+ /* version in dec */ 3745 8 + /* version in dec */
3802 1; /* nul */ 3746 1; /* nul */
3803 name = xmalloc(l); 3747 name = xmalloc(l);
3804 if (stat(absolute_filename, &statbuf) != 0) 3748 if (stat(absolute_filename, &statbuf) != 0)
3805 statbuf.st_mtime = 0; 3749 statbuf.st_mtime = 0;
3806 version = get_module_version(f, str); /* -1 if not found */ 3750 version = get_module_version(f, str); /* -1 if not found */
3807 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", 3751 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d",
3808 symprefix, m_name, absolute_filename, 3752 symprefix, m_name, absolute_filename,
3809 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, 3753 (int)(2 * sizeof(statbuf.st_mtime)), statbuf.st_mtime,
3810 version); 3754 version);
3811 sym = obj_add_symbol(f, name, -1, 3755 sym = obj_add_symbol(f, name, -1,
3812 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), 3756 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
@@ -3819,11 +3763,11 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
3819 /* record where the persistent data is going, same address as previous symbol */ 3763 /* record where the persistent data is going, same address as previous symbol */
3820 3764
3821 if (f->persist) { 3765 if (f->persist) {
3822 l = sizeof(symprefix)+ /* "__insmod_" */ 3766 l = sizeof(symprefix) + /* "__insmod_" */
3823 lm_name+ /* module name */ 3767 lm_name + /* module name */
3824 2+ /* "_P" */ 3768 2 + /* "_P" */
3825 strlen(f->persist)+ /* data store */ 3769 strlen(f->persist) + /* data store */
3826 1; /* nul */ 3770 1; /* nul */
3827 name = xmalloc(l); 3771 name = xmalloc(l);
3828 snprintf(name, l, "%s%s_P%s", 3772 snprintf(name, l, "%s%s_P%s",
3829 symprefix, m_name, f->persist); 3773 symprefix, m_name, f->persist);
@@ -3838,13 +3782,13 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename,
3838 for (i = 0; i < ARRAY_SIZE(section_names); ++i) { 3782 for (i = 0; i < ARRAY_SIZE(section_names); ++i) {
3839 sec = obj_find_section(f, section_names[i]); 3783 sec = obj_find_section(f, section_names[i]);
3840 if (sec && sec->header.sh_size) { 3784 if (sec && sec->header.sh_size) {
3841 l = sizeof(symprefix)+ /* "__insmod_" */ 3785 l = sizeof(symprefix) + /* "__insmod_" */
3842 lm_name+ /* module name */ 3786 lm_name + /* module name */
3843 2+ /* "_S" */ 3787 2 + /* "_S" */
3844 strlen(sec->name)+ /* section name */ 3788 strlen(sec->name) + /* section name */
3845 2+ /* "_L" */ 3789 2 + /* "_L" */
3846 8+ /* length in dec */ 3790 8 + /* length in dec */
3847 1; /* nul */ 3791 1; /* nul */
3848 name = xmalloc(l); 3792 name = xmalloc(l);
3849 snprintf(name, l, "%s%s_S%s_L%ld", 3793 snprintf(name, l, "%s%s_S%s_L%ld",
3850 symprefix, m_name, sec->name, 3794 symprefix, m_name, sec->name,
@@ -3891,9 +3835,10 @@ static void print_load_map(struct obj_file *f)
3891#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL 3835#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3892 /* Quick reference which section indicies are loaded. */ 3836 /* Quick reference which section indicies are loaded. */
3893 3837
3894 loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); 3838 i = f->header.e_shnum;
3839 loaded = alloca(sizeof(int) * i);
3895 while (--i >= 0) 3840 while (--i >= 0)
3896 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; 3841 loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0);
3897 3842
3898 /* Collect the symbols we'll be listing. */ 3843 /* Collect the symbols we'll be listing. */
3899 3844
@@ -3963,7 +3908,7 @@ int insmod_main(int argc, char **argv)
3963 ElfW(Addr) m_addr; 3908 ElfW(Addr) m_addr;
3964 struct obj_file *f; 3909 struct obj_file *f;
3965 struct stat st; 3910 struct stat st;
3966 char *m_name = 0; 3911 char *m_name = NULL;
3967 int exit_status = EXIT_FAILURE; 3912 int exit_status = EXIT_FAILURE;
3968 int m_has_modinfo; 3913 int m_has_modinfo;
3969#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 3914#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
@@ -4027,7 +3972,7 @@ int insmod_main(int argc, char **argv)
4027 m_name = tmp; 3972 m_name = tmp;
4028 } else { 3973 } else {
4029 free(tmp1); 3974 free(tmp1);
4030 tmp1 = 0; /* flag for free(m_name) before exit() */ 3975 tmp1 = NULL; /* flag for free(m_name) before exit() */
4031 } 3976 }
4032 3977
4033 /* Get a filedesc for the module. Check that we have a complete path */ 3978 /* Get a filedesc for the module. Check that we have a complete path */
@@ -4039,7 +3984,6 @@ int insmod_main(int argc, char **argv)
4039 if (k_version) { /* uname succeedd */ 3984 if (k_version) { /* uname succeedd */
4040 char *module_dir; 3985 char *module_dir;
4041 char *tmdn; 3986 char *tmdn;
4042 char real_module_dir[FILENAME_MAX];
4043 3987
4044 tmdn = concat_path_file(_PATH_MODULES, myuname.release); 3988 tmdn = concat_path_file(_PATH_MODULES, myuname.release);
4045 /* Jump through hoops in case /lib/modules/`uname -r` 3989 /* Jump through hoops in case /lib/modules/`uname -r`
@@ -4047,36 +3991,37 @@ int insmod_main(int argc, char **argv)
4047 * follow symlinks, but we do want to follow the 3991 * follow symlinks, but we do want to follow the
4048 * /lib/modules/`uname -r` dir, So resolve it ourselves 3992 * /lib/modules/`uname -r` dir, So resolve it ourselves
4049 * if it is a link... */ 3993 * if it is a link... */
4050 if (realpath(tmdn, real_module_dir) == NULL) 3994 module_dir = xmalloc_readlink(tmdn);
4051 module_dir = tmdn; 3995 if (!module_dir)
4052 else 3996 module_dir = xstrdup(tmdn);
4053 module_dir = real_module_dir;
4054 recursive_action(module_dir, ACTION_RECURSE, 3997 recursive_action(module_dir, ACTION_RECURSE,
4055 check_module_name_match, 0, m_fullName, 0); 3998 check_module_name_match, NULL, m_fullName, 0);
3999 free(module_dir);
4056 free(tmdn); 4000 free(tmdn);
4057 } 4001 }
4058 4002
4059 /* Check if we have found anything yet */ 4003 /* Check if we have found anything yet */
4060 if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) { 4004 if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) {
4061 char module_dir[FILENAME_MAX]; 4005 int r;
4006 char *module_dir;
4062 4007
4063 free(m_filename); 4008 free(m_filename);
4064 m_filename = NULL; 4009 m_filename = NULL;
4065 if (realpath(_PATH_MODULES, module_dir) == NULL) 4010 module_dir = xmalloc_readlink(_PATH_MODULES);
4066 strcpy(module_dir, _PATH_MODULES); 4011 if (!module_dir)
4012 module_dir = xstrdup(_PATH_MODULES);
4067 /* No module found under /lib/modules/`uname -r`, this 4013 /* No module found under /lib/modules/`uname -r`, this
4068 * time cast the net a bit wider. Search /lib/modules/ */ 4014 * time cast the net a bit wider. Search /lib/modules/ */
4069 if (!recursive_action(module_dir, ACTION_RECURSE, 4015 r = recursive_action(module_dir, ACTION_RECURSE,
4070 check_module_name_match, 0, m_fullName, 0) 4016 check_module_name_match, NULL, m_fullName, 0);
4017 if (r)
4018 bb_error_msg_and_die("%s: module not found", m_fullName);
4019 free(module_dir);
4020 if (m_filename == NULL
4021 || ((fp = fopen(m_filename, "r")) == NULL)
4071 ) { 4022 ) {
4072 if (m_filename == 0
4073 || ((fp = fopen(m_filename, "r")) == NULL)
4074 ) {
4075 bb_error_msg("%s: module not found", m_fullName);
4076 goto out;
4077 }
4078 } else
4079 bb_error_msg_and_die("%s: module not found", m_fullName); 4023 bb_error_msg_and_die("%s: module not found", m_fullName);
4024 }
4080 } 4025 }
4081 } else 4026 } else
4082 m_filename = xstrdup(arg1); 4027 m_filename = xstrdup(arg1);
@@ -4093,8 +4038,6 @@ int insmod_main(int argc, char **argv)
4093#endif 4038#endif
4094 4039
4095 f = obj_load(fp, LOADBITS); 4040 f = obj_load(fp, LOADBITS);
4096 if (f == NULL)
4097 bb_perror_msg_and_die("cannot load the module");
4098 4041
4099 if (get_modinfo_value(f, "kernel_version") == NULL) 4042 if (get_modinfo_value(f, "kernel_version") == NULL)
4100 m_has_modinfo = 0; 4043 m_has_modinfo = 0;
@@ -4109,9 +4052,8 @@ int insmod_main(int argc, char **argv)
4109 if (m_has_modinfo) { 4052 if (m_has_modinfo) {
4110 m_version = new_get_module_version(f, m_strversion); 4053 m_version = new_get_module_version(f, m_strversion);
4111 if (m_version == -1) { 4054 if (m_version == -1) {
4112 bb_error_msg("cannot find the kernel version the module was " 4055 bb_error_msg_and_die("cannot find the kernel version the module was "
4113 "compiled for"); 4056 "compiled for");
4114 goto out;
4115 } 4057 }
4116 } 4058 }
4117 4059
@@ -4128,14 +4070,10 @@ int insmod_main(int argc, char **argv)
4128 k_crcs = 0; 4070 k_crcs = 0;
4129#endif /* FEATURE_INSMOD_VERSION_CHECKING */ 4071#endif /* FEATURE_INSMOD_VERSION_CHECKING */
4130 4072
4131 if (!query_module(NULL, 0, NULL, 0, NULL)) { 4073 if (query_module(NULL, 0, NULL, 0, NULL))
4132 if (!new_get_kernel_symbols()) 4074 bb_error_msg_and_die("not configured to support old kernels");
4133 goto out; 4075 new_get_kernel_symbols();
4134 k_crcs = new_is_kernel_checksummed(); 4076 k_crcs = new_is_kernel_checksummed();
4135 } else {
4136 bb_error_msg("not configured to support old kernels");
4137 goto out;
4138 }
4139 4077
4140#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 4078#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
4141 m_crcs = 0; 4079 m_crcs = 0;
@@ -4151,22 +4089,15 @@ int insmod_main(int argc, char **argv)
4151 4089
4152 /* Allocate common symbols, symbol tables, and string tables. */ 4090 /* Allocate common symbols, symbol tables, and string tables. */
4153 4091
4154 if (!new_create_this_module(f, m_name)) { 4092 new_create_this_module(f, m_name);
4155 goto out; 4093 obj_check_undefineds(f);
4156 }
4157
4158 if (!obj_check_undefineds(f)) {
4159 goto out;
4160 }
4161 obj_allocate_commons(f); 4094 obj_allocate_commons(f);
4162 check_tainted_module(f, m_name); 4095 check_tainted_module(f, m_name);
4163 4096
4164 /* done with the module name, on to the optional var=value arguments */ 4097 /* done with the module name, on to the optional var=value arguments */
4165 ++optind; 4098 ++optind;
4166 if (optind < argc) { 4099 if (optind < argc) {
4167 if (!new_process_module_arguments(f, argc - optind, argv + optind)) { 4100 new_process_module_arguments(f, argc - optind, argv + optind);
4168 goto out;
4169 }
4170 } 4101 }
4171 4102
4172 arch_create_got(f); 4103 arch_create_got(f);
@@ -4181,22 +4112,18 @@ int insmod_main(int argc, char **argv)
4181 /* Find current size of the module */ 4112 /* Find current size of the module */
4182 m_size = obj_load_size(f); 4113 m_size = obj_load_size(f);
4183 4114
4184
4185 m_addr = create_module(m_name, m_size); 4115 m_addr = create_module(m_name, m_size);
4186 if (m_addr == -1) switch (errno) { 4116 if (m_addr == -1) switch (errno) {
4187 case EEXIST: 4117 case EEXIST:
4188 bb_error_msg("a module named %s already exists", m_name); 4118 bb_error_msg_and_die("a module named %s already exists", m_name);
4189 goto out;
4190 case ENOMEM: 4119 case ENOMEM:
4191 bb_error_msg("can't allocate kernel memory for module; needed %lu bytes", 4120 bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes",
4192 m_size); 4121 m_size);
4193 goto out;
4194 default: 4122 default:
4195 bb_perror_msg("create_module: %s", m_name); 4123 bb_perror_msg_and_die("create_module: %s", m_name);
4196 goto out;
4197 } 4124 }
4198 4125
4199#if !LOADBITS 4126#if !LOADBITS
4200 /* 4127 /*
4201 * the PROGBITS section was not loaded by the obj_load 4128 * the PROGBITS section was not loaded by the obj_load
4202 * now we can load them directly into the kernel memory 4129 * now we can load them directly into the kernel memory
@@ -4222,7 +4149,7 @@ int insmod_main(int argc, char **argv)
4222 4149
4223 exit_status = EXIT_SUCCESS; 4150 exit_status = EXIT_SUCCESS;
4224 4151
4225out: 4152 out:
4226#if ENABLE_FEATURE_CLEAN_UP 4153#if ENABLE_FEATURE_CLEAN_UP
4227 if (fp) 4154 if (fp)
4228 fclose(fp); 4155 fclose(fp);
@@ -4234,8 +4161,10 @@ out:
4234 return exit_status; 4161 return exit_status;
4235} 4162}
4236 4163
4237 4164#endif /* ENABLE_FEATURE_2_4_MODULES */
4238#endif 4165/*
4166 * End of big piece of 2.4-specific code
4167 */
4239 4168
4240 4169
4241#if ENABLE_FEATURE_2_6_MODULES 4170#if ENABLE_FEATURE_2_6_MODULES
@@ -4249,20 +4178,24 @@ static const char *moderror(int err)
4249{ 4178{
4250 switch (err) { 4179 switch (err) {
4251 case ENOEXEC: 4180 case ENOEXEC:
4252 return "Invalid module format"; 4181 return "invalid module format";
4253 case ENOENT: 4182 case ENOENT:
4254 return "Unknown symbol in module"; 4183 return "unknown symbol in module";
4255 case ESRCH: 4184 case ESRCH:
4256 return "Module has wrong symbol version"; 4185 return "module has wrong symbol version";
4257 case EINVAL: 4186 case EINVAL:
4258 return "Invalid parameters"; 4187 return "invalid parameters";
4259 default: 4188 default:
4260 return strerror(err); 4189 return strerror(err);
4261 } 4190 }
4262} 4191}
4263 4192
4264int insmod_ng_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 4193#if !ENABLE_FEATURE_2_4_MODULES
4265int insmod_ng_main(int argc, char **argv) 4194int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
4195int insmod_main(int argc, char **argv)
4196#else
4197static int insmod_ng_main(int argc, char **argv)
4198#endif
4266{ 4199{
4267 long ret; 4200 long ret;
4268 size_t len; 4201 size_t len;
diff --git a/modutils/lsmod.c b/modutils/lsmod.c
index 70146814c..f1f78ff9f 100644
--- a/modutils/lsmod.c
+++ b/modutils/lsmod.c
@@ -28,17 +28,17 @@ static void check_tainted(void)
28 FILE *f; 28 FILE *f;
29 29
30 tainted = 0; 30 tainted = 0;
31 if ((f = fopen(TAINT_FILENAME, "r"))) { 31 f = fopen(TAINT_FILENAME, "r");
32 if (f) {
32 fscanf(f, "%d", &tainted); 33 fscanf(f, "%d", &tainted);
33 fclose(f); 34 fclose(f);
34 } 35 }
35 if (f && tainted) { 36 if (tainted) {
36 printf(" Tainted: %c%c%c\n", 37 printf(" Tainted: %c%c%c\n",
37 tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', 38 tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
38 tainted & TAINT_FORCED_MODULE ? 'F' : ' ', 39 tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
39 tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); 40 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
40 } 41 } else {
41 else {
42 printf(" Not tainted\n"); 42 printf(" Not tainted\n");
43 } 43 }
44} 44}
@@ -147,7 +147,7 @@ int lsmod_main(int argc, char **argv)
147 147
148 printf("Module Size Used by"); 148 printf("Module Size Used by");
149 check_tainted(); 149 check_tainted();
150#if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT) 150#if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
151 { 151 {
152 char *line; 152 char *line;
153 while ((line = xmalloc_fgets(file)) != NULL) { 153 while ((line = xmalloc_fgets(file)) != NULL) {
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index a67ddea9b..f7d193a05 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -15,6 +15,8 @@
15#include <sys/utsname.h> 15#include <sys/utsname.h>
16#include <fnmatch.h> 16#include <fnmatch.h>
17 17
18#define line_buffer bb_common_bufsiz1
19
18struct mod_opt_t { /* one-way list of options to pass to a module */ 20struct mod_opt_t { /* one-way list of options to pass to a module */
19 char * m_opt_val; 21 char * m_opt_val;
20 struct mod_opt_t * m_next; 22 struct mod_opt_t * m_next;
@@ -48,7 +50,7 @@ struct mod_list_t { /* two-way list of modules to process */
48 50
49static struct dep_t *depend; 51static struct dep_t *depend;
50 52
51#define main_options "acdklnqrst:vVC:" 53#define MAIN_OPT_STR "acdklnqrst:vVC:"
52#define INSERT_ALL 1 /* a */ 54#define INSERT_ALL 1 /* a */
53#define DUMP_CONF_EXIT 2 /* c */ 55#define DUMP_CONF_EXIT 2 /* c */
54#define D_OPT_IGNORED 4 /* d */ 56#define D_OPT_IGNORED 4 /* d */
@@ -63,14 +65,12 @@ static struct dep_t *depend;
63#define VERSION_ONLY 2048 /* V */ 65#define VERSION_ONLY 2048 /* V */
64#define CONFIG_FILE 4096 /* C */ 66#define CONFIG_FILE 4096 /* C */
65 67
66#define autoclean (main_opts & AUTOCLEAN_FLG) 68#define autoclean (option_mask32 & AUTOCLEAN_FLG)
67#define show_only (main_opts & SHOW_ONLY) 69#define show_only (option_mask32 & SHOW_ONLY)
68#define quiet (main_opts & QUIET) 70#define quiet (option_mask32 & QUIET)
69#define remove_opt (main_opts & REMOVE_OPT) 71#define remove_opt (option_mask32 & REMOVE_OPT)
70#define do_syslog (main_opts & DO_SYSLOG) 72#define do_syslog (option_mask32 & DO_SYSLOG)
71#define verbose (main_opts & VERBOSE) 73#define verbose (option_mask32 & VERBOSE)
72
73static int main_opts;
74 74
75static int parse_tag_value(char *buffer, char **ptag, char **pvalue) 75static int parse_tag_value(char *buffer, char **ptag, char **pvalue)
76{ 76{
@@ -78,12 +78,15 @@ static int parse_tag_value(char *buffer, char **ptag, char **pvalue)
78 78
79 buffer = skip_whitespace(buffer); 79 buffer = skip_whitespace(buffer);
80 tag = value = buffer; 80 tag = value = buffer;
81 while (!isspace(*value)) 81 while (!isspace(*value)) {
82 if (!*value) return 0; 82 if (!*value)
83 else value++; 83 return 0;
84 *value++ = 0; 84 value++;
85 }
86 *value++ = '\0';
85 value = skip_whitespace(value); 87 value = skip_whitespace(value);
86 if (!*value) return 0; 88 if (!*value)
89 return 0;
87 90
88 *ptag = tag; 91 *ptag = tag;
89 *pvalue = value; 92 *pvalue = value;
@@ -102,14 +105,14 @@ static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt)
102 while (ol->m_next) { 105 while (ol->m_next) {
103 ol = ol->m_next; 106 ol = ol->m_next;
104 } 107 }
105 ol->m_next = xmalloc(sizeof(struct mod_opt_t)); 108 ol->m_next = xzalloc(sizeof(struct mod_opt_t));
106 ol = ol->m_next; 109 ol = ol->m_next;
107 } else { 110 } else {
108 ol = opt_list = xmalloc(sizeof(struct mod_opt_t)); 111 ol = opt_list = xzalloc(sizeof(struct mod_opt_t));
109 } 112 }
110 113
111 ol->m_opt_val = xstrdup(opt); 114 ol->m_opt_val = xstrdup(opt);
112 ol->m_next = NULL; 115 /*ol->m_next = NULL; - done by xzalloc*/
113 116
114 return opt_list; 117 return opt_list;
115} 118}
@@ -190,7 +193,8 @@ static char *parse_command_string(char *src, char **dst)
190 case '0': 193 case '0':
191 /* We escaped a special character. For now, keep 194 /* We escaped a special character. For now, keep
192 * both the back-slash and the following char. */ 195 * both the back-slash and the following char. */
193 tmp_str++; src++; 196 tmp_str++;
197 src++;
194 break; 198 break;
195 default: 199 default:
196 /* We escaped a space or a single or double quote, 200 /* We escaped a space or a single or double quote,
@@ -242,12 +246,12 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
242 246
243 p = strchr(buffer, '#'); 247 p = strchr(buffer, '#');
244 if (p) 248 if (p)
245 *p = 0; 249 *p = '\0';
246 250
247 l = strlen(buffer); 251 l = strlen(buffer);
248 252
249 while (l && isspace(buffer[l-1])) { 253 while (l && isspace(buffer[l-1])) {
250 buffer[l-1] = 0; 254 buffer[l-1] = '\0';
251 l--; 255 l--;
252 } 256 }
253 257
@@ -256,66 +260,68 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
256 continue; 260 continue;
257 } 261 }
258 262
259 if (!continuation_line) { 263 if (continuation_line)
260 if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) { 264 continue;
261 char *alias, *mod;
262 265
263 if (parse_tag_value(buffer + 6, &alias, &mod)) { 266 if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) {
264 /* handle alias as a module dependent on the aliased module */ 267 char *alias, *mod;
265 if (!*current) {
266 (*first) = (*current) = xzalloc(sizeof(struct dep_t));
267 } else {
268 (*current)->m_next = xzalloc(sizeof(struct dep_t));
269 (*current) = (*current)->m_next;
270 }
271 (*current)->m_name = xstrdup(alias);
272 (*current)->m_isalias = 1;
273 268
274 if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) { 269 if (parse_tag_value(buffer + 6, &alias, &mod)) {
275 (*current)->m_depcnt = 0; 270 /* handle alias as a module dependent on the aliased module */
276 (*current)->m_deparr = 0; 271 if (!*current) {
277 } else { 272 (*first) = (*current) = xzalloc(sizeof(struct dep_t));
278 (*current)->m_depcnt = 1; 273 } else {
279 (*current)->m_deparr = xmalloc(1 * sizeof(char *)); 274 (*current)->m_next = xzalloc(sizeof(struct dep_t));
280 (*current)->m_deparr[0] = xstrdup(mod); 275 (*current) = (*current)->m_next;
281 }
282 (*current)->m_next = 0;
283 } 276 }
284 } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) { 277 (*current)->m_name = xstrdup(alias);
285 char *mod, *opt; 278 (*current)->m_isalias = 1;
286
287 /* split the line in the module/alias name, and options */
288 if (parse_tag_value(buffer + 8, &mod, &opt)) {
289 struct dep_t *dt;
290 279
291 /* find the corresponding module */ 280 if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) {
292 for (dt = *first; dt; dt = dt->m_next) { 281 /*(*current)->m_depcnt = 0; - done by xzalloc */
293 if (strcmp(dt->m_name, mod) == 0) 282 /*(*current)->m_deparr = 0;*/
294 break; 283 } else {
295 } 284 (*current)->m_depcnt = 1;
296 if (dt) { 285 (*current)->m_deparr = xmalloc(sizeof(char *));
297 if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) { 286 (*current)->m_deparr[0] = xstrdup(mod);
298 char* new_opt = NULL;
299 while ((opt = parse_command_string(opt, &new_opt))) {
300 dt->m_options = append_option(dt->m_options, new_opt);
301 }
302 } else {
303 dt->m_options = append_option(dt->m_options, opt);
304 }
305 }
306 } 287 }
307 } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) { 288 /*(*current)->m_next = NULL; - done by xzalloc */
308 int fdi; char *filename; 289 }
290 } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) {
291 char *mod, *opt;
309 292
310 filename = skip_whitespace(buffer + 8); 293 /* split the line in the module/alias name, and options */
294 if (parse_tag_value(buffer + 8, &mod, &opt)) {
295 struct dep_t *dt;
311 296
312 if ((fdi = open(filename, O_RDONLY)) >= 0) { 297 /* find the corresponding module */
313 include_conf(first, current, buffer, buflen, fdi); 298 for (dt = *first; dt; dt = dt->m_next) {
314 close(fdi); 299 if (strcmp(dt->m_name, mod) == 0)
300 break;
315 } 301 }
302 if (dt) {
303 if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) {
304 char* new_opt = NULL;
305 while ((opt = parse_command_string(opt, &new_opt))) {
306 dt->m_options = append_option(dt->m_options, new_opt);
307 }
308 } else {
309 dt->m_options = append_option(dt->m_options, opt);
310 }
311 }
312 }
313 } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {
314 int fdi;
315 char *filename;
316
317 filename = skip_whitespace(buffer + 8);
318 fdi = open(filename, O_RDONLY);
319 if (fdi >= 0) {
320 include_conf(first, current, buffer, buflen, fdi);
321 close(fdi);
316 } 322 }
317 } 323 }
318 } 324 } /* while (reads(...)) */
319} 325}
320 326
321/* 327/*
@@ -327,9 +333,8 @@ static struct dep_t *build_dep(void)
327{ 333{
328 int fd; 334 int fd;
329 struct utsname un; 335 struct utsname un;
330 struct dep_t *first = 0; 336 struct dep_t *first = NULL;
331 struct dep_t *current = 0; 337 struct dep_t *current = NULL;
332 char buffer[2048];
333 char *filename; 338 char *filename;
334 int continuation_line = 0; 339 int continuation_line = 0;
335 int k_version; 340 int k_version;
@@ -350,16 +355,16 @@ static struct dep_t *build_dep(void)
350 /* Ok, that didn't work. Fall back to looking in /lib/modules */ 355 /* Ok, that didn't work. Fall back to looking in /lib/modules */
351 fd = open("/lib/modules/modules.dep", O_RDONLY); 356 fd = open("/lib/modules/modules.dep", O_RDONLY);
352 if (fd < 0) { 357 if (fd < 0) {
353 return 0; 358 bb_error_msg_and_die("cannot parse modules.dep");
354 } 359 }
355 } 360 }
356 361
357 while (reads(fd, buffer, sizeof(buffer))) { 362 while (reads(fd, line_buffer, sizeof(line_buffer))) {
358 int l = strlen(buffer); 363 int l = strlen(line_buffer);
359 char *p = 0; 364 char *p = 0;
360 365
361 while (l > 0 && isspace(buffer[l-1])) { 366 while (l > 0 && isspace(line_buffer[l-1])) {
362 buffer[l-1] = 0; 367 line_buffer[l-1] = '\0';
363 l--; 368 l--;
364 } 369 }
365 370
@@ -371,7 +376,7 @@ static struct dep_t *build_dep(void)
371 /* Is this a new module dep description? */ 376 /* Is this a new module dep description? */
372 if (!continuation_line) { 377 if (!continuation_line) {
373 /* find the dep beginning */ 378 /* find the dep beginning */
374 char *col = strchr(buffer, ':'); 379 char *col = strchr(line_buffer, ':');
375 char *dot = col; 380 char *dot = col;
376 381
377 if (col) { 382 if (col) {
@@ -381,53 +386,52 @@ static struct dep_t *build_dep(void)
381 char *mod; 386 char *mod;
382 387
383 /* Find the beginning of the module file name */ 388 /* Find the beginning of the module file name */
384 *col = 0; 389 *col = '\0';
385 mods = bb_basename(buffer); 390 mods = bb_basename(line_buffer);
386 391
387 /* find the path of the module */ 392 /* find the path of the module */
388 modpath = strchr(buffer, '/'); /* ... and this is the path */ 393 modpath = strchr(line_buffer, '/'); /* ... and this is the path */
389 if (!modpath) 394 if (!modpath)
390 modpath = buffer; /* module with no path */ 395 modpath = line_buffer; /* module with no path */
391 /* find the end of the module name in the file name */ 396 /* find the end of the module name in the file name */
392 if (ENABLE_FEATURE_2_6_MODULES && 397 if (ENABLE_FEATURE_2_6_MODULES &&
393 (k_version > 4) && (*(col-3) == '.') && 398 (k_version > 4) && (col[-3] == '.') &&
394 (*(col-2) == 'k') && (*(col-1) == 'o')) 399 (col[-2] == 'k') && (col[-1] == 'o'))
395 dot = col - 3; 400 dot = col - 3;
396 else 401 else if ((col[-2] == '.') && (col[-1] == 'o'))
397 if ((*(col-2) == '.') && (*(col-1) == 'o')) 402 dot = col - 2;
398 dot = col - 2;
399 403
400 mod = xstrndup(mods, dot - mods); 404 mod = xstrndup(mods, dot - mods);
401 405
402 /* enqueue new module */ 406 /* enqueue new module */
403 if (!current) { 407 if (!current) {
404 first = current = xmalloc(sizeof(struct dep_t)); 408 first = current = xzalloc(sizeof(struct dep_t));
405 } else { 409 } else {
406 current->m_next = xmalloc(sizeof(struct dep_t)); 410 current->m_next = xzalloc(sizeof(struct dep_t));
407 current = current->m_next; 411 current = current->m_next;
408 } 412 }
409 current->m_name = mod; 413 current->m_name = mod;
410 current->m_path = xstrdup(modpath); 414 current->m_path = xstrdup(modpath);
411 current->m_options = NULL; 415 /*current->m_options = NULL; - xzalloc did it*/
412 current->m_isalias = 0; 416 /*current->m_isalias = 0;*/
413 current->m_depcnt = 0; 417 /*current->m_depcnt = 0;*/
414 current->m_deparr = 0; 418 /*current->m_deparr = 0;*/
415 current->m_next = 0; 419 /*current->m_next = 0;*/
416 420
417 p = col + 1; 421 p = col + 1;
418 } else 422 } else
419 /* this line is not a dep description */ 423 /* this line is not a dep description */
420 p = 0; 424 p = NULL;
421 } else 425 } else
422 /* It's a dep description continuation */ 426 /* It's a dep description continuation */
423 p = buffer; 427 p = line_buffer;
424 428
425 while (p && *p && isblank(*p)) 429 while (p && *p && isblank(*p))
426 p++; 430 p++;
427 431
428 /* p points to the first dependable module; if NULL, no dependable module */ 432 /* p points to the first dependable module; if NULL, no dependable module */
429 if (p && *p) { 433 if (p && *p) {
430 char *end = &buffer[l-1]; 434 char *end = &line_buffer[l-1];
431 const char *deps; 435 const char *deps;
432 char *dep; 436 char *dep;
433 char *next; 437 char *next;
@@ -440,7 +444,7 @@ static struct dep_t *build_dep(void)
440 /* search the end of the dependency */ 444 /* search the end of the dependency */
441 next = strchr(p, ' '); 445 next = strchr(p, ' ');
442 if (next) { 446 if (next) {
443 *next = 0; 447 *next = '\0';
444 next--; 448 next--;
445 } else 449 } else
446 next = end; 450 next = end;
@@ -454,12 +458,11 @@ static struct dep_t *build_dep(void)
454 458
455 /* find the end of the module name in the file name */ 459 /* find the end of the module name in the file name */
456 if (ENABLE_FEATURE_2_6_MODULES 460 if (ENABLE_FEATURE_2_6_MODULES
457 && (k_version > 4) && (*(next-2) == '.') 461 && (k_version > 4) && (next[-2] == '.')
458 && (*(next-1) == 'k') && (*next == 'o')) 462 && (next[-1] == 'k') && (next[0] == 'o'))
459 ext = 3; 463 ext = 3;
460 else 464 else if ((next[-1] == '.') && (next[0] == 'o'))
461 if ((*(next-1) == '.') && (*next == 'o')) 465 ext = 2;
462 ext = 2;
463 466
464 /* Cope with blank lines */ 467 /* Cope with blank lines */
465 if ((next-deps-ext+1) <= 0) 468 if ((next-deps-ext+1) <= 0)
@@ -477,11 +480,8 @@ static struct dep_t *build_dep(void)
477 } 480 }
478 481
479 /* is there other dependable module(s) ? */ 482 /* is there other dependable module(s) ? */
480 if (buffer[l-1] == '\\') 483 continuation_line = (line_buffer[l-1] == '\\');
481 continuation_line = 1; 484 } /* while (reads(...)) */
482 else
483 continuation_line = 0;
484 }
485 close(fd); 485 close(fd);
486 486
487 /* 487 /*
@@ -498,7 +498,7 @@ static struct dep_t *build_dep(void)
498 fd = open("/etc/conf.modules", O_RDONLY); 498 fd = open("/etc/conf.modules", O_RDONLY);
499 499
500 if (fd >= 0) { 500 if (fd >= 0) {
501 include_conf(&first, &current, buffer, sizeof(buffer), fd); 501 include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
502 close(fd); 502 close(fd);
503 } 503 }
504 504
@@ -515,7 +515,7 @@ static struct dep_t *build_dep(void)
515 free(filename); 515 free(filename);
516 516
517 if (fd >= 0) { 517 if (fd >= 0) {
518 include_conf(&first, &current, buffer, sizeof(buffer), fd); 518 include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
519 close(fd); 519 close(fd);
520 } 520 }
521 521
@@ -530,7 +530,7 @@ static struct dep_t *build_dep(void)
530 free(filename); 530 free(filename);
531 531
532 if (fd >= 0) { 532 if (fd >= 0) {
533 include_conf(&first, &current, buffer, sizeof(buffer), fd); 533 include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
534 close(fd); 534 close(fd);
535 } 535 }
536 } 536 }
@@ -542,16 +542,15 @@ static struct dep_t *build_dep(void)
542static int already_loaded(const char *name) 542static int already_loaded(const char *name)
543{ 543{
544 int fd, ret = 0; 544 int fd, ret = 0;
545 char buffer[4096];
546 545
547 fd = open("/proc/modules", O_RDONLY); 546 fd = open("/proc/modules", O_RDONLY);
548 if (fd < 0) 547 if (fd < 0)
549 return -1; 548 return -1;
550 549
551 while (reads(fd, buffer, sizeof(buffer))) { 550 while (reads(fd, line_buffer, sizeof(line_buffer))) {
552 char *p; 551 char *p;
553 552
554 p = strchr (buffer, ' '); 553 p = strchr(line_buffer, ' ');
555 if (p) { 554 if (p) {
556 const char *n; 555 const char *n;
557 556
@@ -559,8 +558,8 @@ static int already_loaded(const char *name)
559 // the idiosyncrasy that _ and - are interchangeable because the 558 // the idiosyncrasy that _ and - are interchangeable because the
560 // 2.6 kernel does weird things. 559 // 2.6 kernel does weird things.
561 560
562 *p = 0; 561 *p = '\0';
563 for (p = buffer, n = name; ; p++, n++) { 562 for (p = line_buffer, n = name; ; p++, n++) {
564 if (*p != *n) { 563 if (*p != *n) {
565 if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-')) 564 if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-'))
566 continue; 565 continue;
@@ -574,8 +573,8 @@ static int already_loaded(const char *name)
574 } 573 }
575 } 574 }
576 } 575 }
577done: 576 done:
578 close (fd); 577 close(fd);
579 return ret; 578 return ret;
580} 579}
581 580
@@ -623,7 +622,7 @@ static int mod_process(const struct mod_list_t *list, int do_insert)
623 while (opts) { 622 while (opts) {
624 /* Add one more option */ 623 /* Add one more option */
625 argc++; 624 argc++;
626 argv = xrealloc(argv,(argc + 1)* sizeof(char*)); 625 argv = xrealloc(argv, (argc + 1) * sizeof(char*));
627 argv[argc-1] = opts->m_opt_val; 626 argv[argc-1] = opts->m_opt_val;
628 opts = opts->m_next; 627 opts = opts->m_next;
629 } 628 }
@@ -698,9 +697,8 @@ static int check_pattern(const char* pat_src, const char* mod_src)
698 } 697 }
699 698
700 return ret; 699 return ret;
701 } else {
702 return fnmatch(pat_src, mod_src, 0);
703 } 700 }
701 return fnmatch(pat_src, mod_src, 0);
704} 702}
705 703
706/* 704/*
@@ -712,8 +710,8 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
712{ 710{
713 struct mod_list_t *find; 711 struct mod_list_t *find;
714 struct dep_t *dt; 712 struct dep_t *dt;
715 struct mod_opt_t *opt = 0; 713 struct mod_opt_t *opt = NULL;
716 char *path = 0; 714 char *path = NULL;
717 715
718 /* Search for the given module name amongst all dependency rules. 716 /* Search for the given module name amongst all dependency rules.
719 * The module name in a dependency rule can be a shell pattern, 717 * The module name in a dependency rule can be a shell pattern,
@@ -765,8 +763,8 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
765 763
766 // search for duplicates 764 // search for duplicates
767 for (find = *head; find; find = find->m_next) { 765 for (find = *head; find; find = find->m_next) {
768 if (!strcmp(mod, find->m_name)) { 766 if (strcmp(mod, find->m_name) == 0) {
769 // found ->dequeue it 767 // found -> dequeue it
770 768
771 if (find->m_prev) 769 if (find->m_prev)
772 find->m_prev->m_next = find->m_next; 770 find->m_prev->m_next = find->m_next;
@@ -783,7 +781,7 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
783 } 781 }
784 782
785 if (!find) { // did not find a duplicate 783 if (!find) { // did not find a duplicate
786 find = xmalloc(sizeof(struct mod_list_t)); 784 find = xzalloc(sizeof(struct mod_list_t));
787 find->m_name = mod; 785 find->m_name = mod;
788 find->m_path = path; 786 find->m_path = path;
789 find->m_options = opt; 787 find->m_options = opt;
@@ -793,7 +791,7 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t
793 if (*tail) 791 if (*tail)
794 (*tail)->m_next = find; 792 (*tail)->m_next = find;
795 find->m_prev = *tail; 793 find->m_prev = *tail;
796 find->m_next = 0; 794 /*find->m_next = NULL; - xzalloc did it */
797 795
798 if (!*head) 796 if (!*head)
799 *head = find; 797 *head = find;
@@ -868,11 +866,11 @@ int modprobe_main(int argc, char **argv)
868 char *unused; 866 char *unused;
869 867
870 opt_complementary = "?V-:q-v:v-q"; 868 opt_complementary = "?V-:q-v:v-q";
871 main_opts = getopt32(argv, "acdklnqrst:vVC:", 869 getopt32(argv, MAIN_OPT_STR, &unused, &unused);
872 &unused, &unused); 870
873 if (main_opts & (DUMP_CONF_EXIT | LIST_ALL)) 871 if (option_mask32 & (DUMP_CONF_EXIT | LIST_ALL))
874 return EXIT_SUCCESS; 872 return EXIT_SUCCESS;
875 if (main_opts & (RESTRICT_DIR | CONFIG_FILE)) 873 if (option_mask32 & (RESTRICT_DIR | CONFIG_FILE))
876 bb_error_msg_and_die("-t and -C not supported"); 874 bb_error_msg_and_die("-t and -C not supported");
877 875
878 depend = build_dep(); 876 depend = build_dep();
@@ -882,8 +880,8 @@ int modprobe_main(int argc, char **argv)
882 880
883 if (remove_opt) { 881 if (remove_opt) {
884 do { 882 do {
885 if (mod_remove(optind < argc ? 883 /* argv[optind] can be NULL here */
886 argv[optind] : NULL)) { 884 if (mod_remove(argv[optind])) {
887 bb_error_msg("failed to remove module %s", 885 bb_error_msg("failed to remove module %s",
888 argv[optind]); 886 argv[optind]);
889 rc = EXIT_FAILURE; 887 rc = EXIT_FAILURE;