| @@ -67,25 +67,21 @@ |
| #define ENABLE_FEATURE_2_4_MODULES 1 |
| #endif |
| |
| - | #if !ENABLE_FEATURE_2_4_MODULES |
| - | #define insmod_ng_main insmod_main |
| - | #endif |
| + | /* |
| + | * Big piece of 2.4-specific code |
| + | */ |
| + | #if ENABLE_FEATURE_2_4_MODULES |
| |
| #if ENABLE_FEATURE_2_6_MODULES |
| - | extern int insmod_ng_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| + | static int insmod_ng_main(int argc, char **argv); |
| #endif |
| |
| - | |
| - | #if ENABLE_FEATURE_2_4_MODULES |
| - | |
| - | |
| #if ENABLE_FEATURE_INSMOD_LOADINKMEM |
| #define LOADBITS 0 |
| #else |
| #define LOADBITS 1 |
| #endif |
| |
| - | |
| /* Alpha */ |
| #if defined(__alpha__) |
| #define MATCH_MACHINE(x) (x == EM_ALPHA) |
| @@ -627,13 +623,13 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, |
| |
| static void *obj_extend_section(struct obj_section *sec, unsigned long more); |
| |
| - | static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| + | static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| const char *string); |
| |
| - | static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| + | static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| struct obj_symbol *sym); |
| |
| - | static int obj_check_undefineds(struct obj_file *f); |
| + | static void obj_check_undefineds(struct obj_file *f); |
| |
| static void obj_allocate_commons(struct obj_file *f); |
| |
| @@ -788,7 +784,6 @@ static size_t nksyms; |
| static struct external_module *ext_modules; |
| static int n_ext_modules; |
| static int n_ext_modules_used; |
| - | extern int delete_module(const char *); |
| |
| static char *m_filename; |
| static char *m_fullName; |
| @@ -801,19 +796,16 @@ static int check_module_name_match(const char *filename, struct stat *statbuf, |
| void *userdata, int depth) |
| { |
| char *fullname = (char *) userdata; |
| + | char *tmp; |
| |
| if (fullname[0] == '\0') |
| return FALSE; |
| - | else { |
| - | char *tmp, *tmp1 = xstrdup(filename); |
| - | tmp = bb_get_last_path_component_nostrip(tmp1); |
| - | if (strcmp(tmp, fullname) == 0) { |
| - | free(tmp1); |
| - | /* Stop searching if we find a match */ |
| - | m_filename = xstrdup(filename); |
| - | return FALSE; |
| - | } |
| - | free(tmp1); |
| + | |
| + | tmp = bb_get_last_path_component_nostrip(filename); |
| + | if (strcmp(tmp, fullname) == 0) { |
| + | /* Stop searching if we find a match */ |
| + | m_filename = xstrdup(filename); |
| + | return FALSE; |
| } |
| return TRUE; |
| } |
| @@ -824,25 +816,19 @@ static int check_module_name_match(const char *filename, struct stat *statbuf, |
| static struct obj_file *arch_new_file(void) |
| { |
| struct arch_file *f; |
| - | f = xmalloc(sizeof(*f)); |
| - | |
| - | memset(f, 0, sizeof(*f)); |
| - | |
| - | return &f->root; |
| + | f = xzalloc(sizeof(*f)); |
| + | return &f->root; /* it's a first member */ |
| } |
| |
| static struct obj_section *arch_new_section(void) |
| { |
| - | return xmalloc(sizeof(struct obj_section)); |
| + | return xzalloc(sizeof(struct obj_section)); |
| } |
| |
| static struct obj_symbol *arch_new_symbol(void) |
| { |
| struct arch_symbol *sym; |
| - | sym = xmalloc(sizeof(*sym)); |
| - | |
| - | memset(sym, 0, sizeof(*sym)); |
| - | |
| + | sym = xzalloc(sizeof(*sym)); |
| return &sym->root; |
| } |
| |
| @@ -2210,7 +2196,6 @@ static struct obj_section *obj_create_alloced_section(struct obj_file *f, |
| f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); |
| f->sections[newidx] = sec = arch_new_section(); |
| |
| - | memset(sec, 0, sizeof(*sec)); |
| sec->header.sh_type = SHT_PROGBITS; |
| sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
| sec->header.sh_size = size; |
| @@ -2236,7 +2221,6 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, |
| f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); |
| f->sections[newidx] = sec = arch_new_section(); |
| |
| - | memset(sec, 0, sizeof(*sec)); |
| sec->header.sh_type = SHT_PROGBITS; |
| sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
| sec->header.sh_size = size; |
| @@ -2398,7 +2382,7 @@ static char *get_modinfo_value(struct obj_file *f, const char *key) |
| /*======================================================================*/ |
| /* Functions relating to module loading after 2.1.18. */ |
| |
| - | static int |
| + | static void |
| new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| { |
| while (argc > 0) { |
| @@ -2408,7 +2392,8 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| int min, max, n; |
| |
| p = *argv; |
| - | if ((q = strchr(p, '=')) == NULL) { |
| + | q = strchr(p, '='); |
| + | if (q == NULL) { |
| argc--; |
| continue; |
| } |
| @@ -2421,8 +2406,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| p = get_modinfo_value(f, key); |
| key += 5; |
| if (p == NULL) { |
| - | bb_error_msg("invalid parameter %s", key); |
| - | return 0; |
| + | bb_error_msg_and_die("invalid parameter %s", key); |
| } |
| |
| #ifdef SYMBOL_PREFIX |
| @@ -2436,8 +2420,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| |
| /* Also check that the parameter was not resolved from the kernel. */ |
| if (sym == NULL || sym->secidx > SHN_HIRESERVE) { |
| - | bb_error_msg("symbol for parameter %s not found", key); |
| - | return 0; |
| + | bb_error_msg_and_die("symbol for parameter %s not found", key); |
| } |
| |
| if (isdigit(*p)) { |
| @@ -2463,11 +2446,10 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| |
| str = alloca(strlen(q)); |
| for (r = str, q++; *q != '"'; ++q, ++r) { |
| - | if (*q == '\0') { |
| - | bb_error_msg("improperly terminated string argument for %s", |
| + | if (*q == '\0') |
| + | bb_error_msg_and_die("improperly terminated string argument for %s", |
| key); |
| - | return 0; |
| - | } else if (*q == '\\') |
| + | if (*q == '\\') |
| switch (*++q) { |
| case 'a': |
| *r = '\a'; |
| @@ -2513,8 +2495,9 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| default: |
| *r = *q; |
| break; |
| - | } else |
| - | *r = *q; |
| + | } |
| + | else |
| + | *r = *q; |
| } |
| *r = '\0'; |
| ++q; |
| @@ -2558,17 +2541,15 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| /* Get the size of each member */ |
| /* Probably we should do that outside the loop ? */ |
| if (!isdigit(*(p + 1))) { |
| - | bb_error_msg("parameter type 'c' for %s must be followed by" |
| + | bb_error_msg_and_die("parameter type 'c' for %s must be followed by" |
| " the maximum size", key); |
| - | return 0; |
| } |
| charssize = strtoul(p + 1, (char **) NULL, 10); |
| |
| /* Check length */ |
| if (strlen(str) >= charssize) { |
| - | bb_error_msg("string too long for %s (max %ld)", key, |
| + | bb_error_msg_and_die("string too long for %s (max %ld)", key, |
| charssize - 1); |
| - | return 0; |
| } |
| |
| /* Copy to location */ |
| @@ -2595,12 +2576,10 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| break; |
| |
| default: |
| - | bb_error_msg("unknown parameter type '%c' for %s", *p, key); |
| - | return 0; |
| + | bb_error_msg_and_die("unknown parameter type '%c' for %s", *p, key); |
| } |
| } |
| - | |
| - | retry_end_of_value: |
| + | retry_end_of_value: |
| switch (*q) { |
| case '\0': |
| goto end_of_arg; |
| @@ -2614,28 +2593,23 @@ retry_end_of_value: |
| |
| case ',': |
| if (++n > max) { |
| - | bb_error_msg("too many values for %s (max %d)", key, max); |
| - | return 0; |
| + | bb_error_msg_and_die("too many values for %s (max %d)", key, max); |
| } |
| ++q; |
| break; |
| |
| default: |
| - | bb_error_msg("invalid argument syntax for %s", key); |
| - | return 0; |
| + | bb_error_msg_and_die("invalid argument syntax for %s", key); |
| } |
| } |
| - | |
| - | end_of_arg: |
| + | end_of_arg: |
| if (n < min) { |
| - | bb_error_msg("too few values for %s (min %d)", key, min); |
| - | return 0; |
| + | bb_error_msg_and_die("too few values for %s (min %d)", key, min); |
| } |
| |
| - | argc--, argv++; |
| + | argc--; |
| + | argv++; |
| } |
| - | |
| - | return 1; |
| } |
| |
| #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING |
| @@ -2644,8 +2618,7 @@ static int new_is_module_checksummed(struct obj_file *f) |
| const char *p = get_modinfo_value(f, "using_checksums"); |
| if (p) |
| return xatoi(p); |
| - | else |
| - | return 0; |
| + | return 0; |
| } |
| |
| /* 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]) |
| |
| /* Fetch the loaded modules, and all currently exported symbols. */ |
| |
| - | static int new_get_kernel_symbols(void) |
| + | static void new_get_kernel_symbols(void) |
| { |
| char *module_names, *mn; |
| struct external_module *modules, *m; |
| @@ -2688,15 +2661,17 @@ static int new_get_kernel_symbols(void) |
| |
| /* Collect the loaded modules. */ |
| |
| - | module_names = xmalloc(bufsize = 256); |
| - | retry_modules_load: |
| + | bufsize = 256; |
| + | module_names = xmalloc(bufsize); |
| + | |
| + | retry_modules_load: |
| if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { |
| if (errno == ENOSPC && bufsize < ret) { |
| - | module_names = xrealloc(module_names, bufsize = ret); |
| + | bufsize = ret; |
| + | module_names = xrealloc(module_names, bufsize); |
| goto retry_modules_load; |
| } |
| - | bb_perror_msg("QM_MODULES"); |
| - | return 0; |
| + | bb_perror_msg_and_die("QM_MODULES"); |
| } |
| |
| n_ext_modules = nmod = ret; |
| @@ -2715,23 +2690,23 @@ retry_modules_load: |
| /* The module was removed out from underneath us. */ |
| continue; |
| } |
| - | bb_perror_msg("query_module: QM_INFO: %s", mn); |
| - | return 0; |
| + | bb_perror_msg_and_die("query_module: QM_INFO: %s", mn); |
| } |
| |
| - | syms = xmalloc(bufsize = 1024); |
| - | retry_mod_sym_load: |
| + | bufsize = 1024; |
| + | syms = xmalloc(bufsize); |
| + | retry_mod_sym_load: |
| if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { |
| switch (errno) { |
| case ENOSPC: |
| - | syms = xrealloc(syms, bufsize = ret); |
| + | bufsize = ret; |
| + | syms = xrealloc(syms, bufsize); |
| goto retry_mod_sym_load; |
| case ENOENT: |
| /* The module was removed out from underneath us. */ |
| continue; |
| default: |
| - | bb_perror_msg("query_module: QM_SYMBOLS: %s", mn); |
| - | return 0; |
| + | bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn); |
| } |
| } |
| nsyms = ret; |
| @@ -2750,14 +2725,13 @@ retry_mod_sym_load: |
| /* Collect the kernel's symbols. */ |
| |
| syms = xmalloc(bufsize = 16 * 1024); |
| - | retry_kern_sym_load: |
| + | retry_kern_sym_load: |
| if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { |
| if (errno == ENOSPC && bufsize < ret) { |
| syms = xrealloc(syms, bufsize = ret); |
| goto retry_kern_sym_load; |
| } |
| - | bb_perror_msg("kernel: QM_SYMBOLS"); |
| - | return 0; |
| + | bb_perror_msg_and_die("kernel: QM_SYMBOLS"); |
| } |
| nksyms = nsyms = ret; |
| ksyms = syms; |
| @@ -2765,7 +2739,6 @@ retry_kern_sym_load: |
| for (j = 0, s = syms; j < nsyms; ++j, ++s) { |
| s->name += (unsigned long) syms; |
| } |
| - | return 1; |
| } |
| |
| |
| @@ -2786,7 +2759,7 @@ static int new_is_kernel_checksummed(void) |
| } |
| |
| |
| - | static int new_create_this_module(struct obj_file *f, const char *m_name) |
| + | static void new_create_this_module(struct obj_file *f, const char *m_name) |
| { |
| struct obj_section *sec; |
| |
| @@ -2800,8 +2773,6 @@ static int new_create_this_module(struct obj_file *f, const char *m_name) |
| |
| obj_string_patch(f, sec->idx, offsetof(struct new_module, name), |
| m_name); |
| - | |
| - | return 1; |
| } |
| |
| #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) |
| |
| /*======================================================================*/ |
| |
| - | static int |
| + | static void |
| obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| const char *string) |
| { |
| @@ -3010,11 +2981,9 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| loc = obj_extend_section(strsec, len); |
| } |
| memcpy(loc, string, len); |
| - | |
| - | return 1; |
| } |
| |
| - | static int |
| + | static void |
| obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| struct obj_symbol *sym) |
| { |
| @@ -3026,14 +2995,11 @@ obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| p->reloc_offset = offset; |
| p->sym = sym; |
| f->symbol_patches = p; |
| - | |
| - | return 1; |
| } |
| |
| - | static int obj_check_undefineds(struct obj_file *f) |
| + | static void obj_check_undefineds(struct obj_file *f) |
| { |
| - | unsigned long i; |
| - | int ret = 1; |
| + | unsigned i; |
| |
| for (i = 0; i < HASH_BUCKETS; ++i) { |
| struct obj_symbol *sym; |
| @@ -3043,15 +3009,11 @@ static int obj_check_undefineds(struct obj_file *f) |
| sym->secidx = SHN_ABS; |
| sym->value = 0; |
| } else { |
| - | if (!flag_quiet) { |
| - | bb_error_msg("unresolved symbol %s", sym->name); |
| - | } |
| - | ret = 0; |
| + | if (!flag_quiet) |
| + | bb_error_msg_and_die("unresolved symbol %s", sym->name); |
| } |
| } |
| } |
| - | |
| - | return ret; |
| } |
| |
| static void obj_allocate_commons(struct obj_file *f) |
| @@ -3114,7 +3076,6 @@ static void obj_allocate_commons(struct obj_file *f) |
| f->sections[i] = sec = arch_new_section(); |
| f->header.e_shnum = i + 1; |
| |
| - | memset(sec, 0, sizeof(*sec)); |
| sec->header.sh_type = SHT_PROGBITS; |
| sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
| sec->name = ".bss"; |
| @@ -3347,44 +3308,38 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| /* Read the file header. */ |
| |
| f = arch_new_file(); |
| - | memset(f, 0, sizeof(*f)); |
| f->symbol_cmp = strcmp; |
| f->symbol_hash = obj_elf_hash; |
| f->load_order_search_start = &f->load_order; |
| |
| fseek(fp, 0, SEEK_SET); |
| if (fread(&f->header, sizeof(f->header), 1, fp) != 1) { |
| - | bb_perror_msg("error reading ELF header"); |
| - | return NULL; |
| + | bb_perror_msg_and_die("error reading ELF header"); |
| } |
| |
| if (f->header.e_ident[EI_MAG0] != ELFMAG0 |
| || f->header.e_ident[EI_MAG1] != ELFMAG1 |
| || f->header.e_ident[EI_MAG2] != ELFMAG2 |
| || f->header.e_ident[EI_MAG3] != ELFMAG3) { |
| - | bb_error_msg("not an ELF file"); |
| - | return NULL; |
| + | bb_error_msg_and_die("not an ELF file"); |
| } |
| if (f->header.e_ident[EI_CLASS] != ELFCLASSM |
| || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN |
| ? ELFDATA2MSB : ELFDATA2LSB) |
| || f->header.e_ident[EI_VERSION] != EV_CURRENT |
| || !MATCH_MACHINE(f->header.e_machine)) { |
| - | bb_error_msg("ELF file not for this architecture"); |
| - | return NULL; |
| + | bb_error_msg_and_die("ELF file not for this architecture"); |
| } |
| if (f->header.e_type != ET_REL) { |
| - | bb_error_msg("ELF file not a relocatable object"); |
| - | return NULL; |
| + | bb_error_msg_and_die("ELF file not a relocatable object"); |
| } |
| |
| /* Read the section headers. */ |
| |
| if (f->header.e_shentsize != sizeof(ElfW(Shdr))) { |
| - | bb_error_msg("section header size mismatch: %lu != %lu", |
| + | bb_error_msg_and_die("section header size mismatch: %lu != %lu", |
| (unsigned long) f->header.e_shentsize, |
| (unsigned long) sizeof(ElfW(Shdr))); |
| - | return NULL; |
| } |
| |
| shnum = f->header.e_shnum; |
| @@ -3394,8 +3349,7 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); |
| fseek(fp, f->header.e_shoff, SEEK_SET); |
| if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) { |
| - | bb_perror_msg("error reading ELF section headers"); |
| - | return NULL; |
| + | bb_perror_msg_and_die("error reading ELF section headers"); |
| } |
| |
| /* Read the section data. */ |
| @@ -3404,7 +3358,6 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| struct obj_section *sec; |
| |
| f->sections[i] = sec = arch_new_section(); |
| - | memset(sec, 0, sizeof(*sec)); |
| |
| sec->header = section_headers[i]; |
| sec->idx = i; |
| @@ -3431,8 +3384,7 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| sec->contents = xmalloc(sec->header.sh_size); |
| fseek(fp, sec->header.sh_offset, SEEK_SET); |
| if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { |
| - | bb_perror_msg("error reading ELF section data"); |
| - | return NULL; |
| + | bb_perror_msg_and_die("error reading ELF section data"); |
| } |
| } else { |
| sec->contents = NULL; |
| @@ -3441,14 +3393,11 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| |
| #if SHT_RELM == SHT_REL |
| case SHT_RELA: |
| - | bb_error_msg("RELA relocations not supported on this architecture"); |
| - | return NULL; |
| + | bb_error_msg_and_die("RELA relocations not supported on this architecture"); |
| #else |
| case SHT_REL: |
| - | bb_error_msg("REL relocations not supported on this architecture"); |
| - | return NULL; |
| + | bb_error_msg_and_die("REL relocations not supported on this architecture"); |
| #endif |
| - | |
| default: |
| if (sec->header.sh_type >= SHT_LOPROC) { |
| /* Assume processor specific section types are debug |
| @@ -3458,9 +3407,8 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| break; |
| } |
| |
| - | bb_error_msg("can't handle sections of type %ld", |
| + | bb_error_msg_and_die("can't handle sections of type %ld", |
| (long) sec->header.sh_type); |
| - | return NULL; |
| } |
| } |
| } |
| @@ -3494,10 +3442,9 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| ElfW(Sym) * sym; |
| |
| if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { |
| - | bb_error_msg("symbol size mismatch: %lu != %lu", |
| + | bb_error_msg_and_die("symbol size mismatch: %lu != %lu", |
| (unsigned long) sec->header.sh_entsize, |
| (unsigned long) sizeof(ElfW(Sym))); |
| - | return NULL; |
| } |
| |
| nsym = sec->header.sh_size / sizeof(ElfW(Sym)); |
| @@ -3528,7 +3475,6 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| */ |
| val |= sym->st_other & 4; |
| #endif |
| - | |
| obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, |
| val, sym->st_size); |
| } |
| @@ -3537,10 +3483,9 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) |
| |
| case SHT_RELM: |
| if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { |
| - | bb_error_msg("relocation entry size mismatch: %lu != %lu", |
| + | bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu", |
| (unsigned long) sec->header.sh_entsize, |
| (unsigned long) sizeof(ElfW(RelM))); |
| - | return NULL; |
| } |
| break; |
| /* 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) |
| } |
| return 2; |
| } |
| - | if (strchr(ptr, '\0')) |
| - | ptr = strchr(ptr, '\0') + 1; |
| + | ptr = strchr(ptr, '\0'); |
| + | if (ptr) |
| + | ptr++; |
| else |
| ptr = endptr; |
| } |
| @@ -3648,12 +3594,12 @@ static int obj_gpl_license(struct obj_file *f, const char **license) |
| } |
| |
| #define TAINT_FILENAME "/proc/sys/kernel/tainted" |
| - | #define TAINT_PROPRIETORY_MODULE (1<<0) |
| - | #define TAINT_FORCED_MODULE (1<<1) |
| - | #define TAINT_UNSAFE_SMP (1<<2) |
| + | #define TAINT_PROPRIETORY_MODULE (1 << 0) |
| + | #define TAINT_FORCED_MODULE (1 << 1) |
| + | #define TAINT_UNSAFE_SMP (1 << 2) |
| #define TAINT_URL "http://www.tux.org/lkml/#export-tainted" |
| |
| - | static void set_tainted(struct obj_file *f, int fd, char *m_name, |
| + | static void set_tainted(int fd, char *m_name, |
| int kernel_has_tainted, int taint, const char *text1, const char *text2) |
| { |
| static smallint printed_info; |
| @@ -3703,22 +3649,22 @@ static void check_tainted_module(struct obj_file *f, char *m_name) |
| case 0: |
| break; |
| case 1: |
| - | set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", ""); |
| + | set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", ""); |
| break; |
| case 2: |
| /* The module has a non-GPL license so we pretend that the |
| * kernel always has a taint flag to get a warning even on |
| * kernels without the proc flag. |
| */ |
| - | set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); |
| + | set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); |
| break; |
| default: |
| - | set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); |
| + | set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); |
| break; |
| } |
| |
| if (flag_force_load) |
| - | set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", ""); |
| + | set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", ""); |
| |
| if (fd >= 0) |
| close(fd); |
| @@ -3752,15 +3698,7 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, |
| const char *m_name) |
| { |
| static const char symprefix[] ALIGN1 = "__insmod_"; |
| - | |
| - | struct obj_section *sec; |
| - | struct obj_symbol *sym; |
| - | char *name, *absolute_filename; |
| - | char str[STRVERSIONLEN], real[PATH_MAX]; |
| - | int i, l, lm_name, lfilename, use_ksymtab, version; |
| - | struct stat statbuf; |
| - | |
| - | static const char *section_names[] = { |
| + | static const char section_names[][8] = { |
| ".text", |
| ".rodata", |
| ".data", |
| @@ -3768,12 +3706,18 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, |
| ".sbss" |
| }; |
| |
| - | if (realpath(filename, real)) { |
| - | absolute_filename = xstrdup(real); |
| - | } else { |
| - | bb_perror_msg("cannot get realpath for %s", filename); |
| + | struct obj_section *sec; |
| + | struct obj_symbol *sym; |
| + | char *name, *absolute_filename; |
| + | char str[STRVERSIONLEN]; |
| + | int i, l, lm_name, lfilename, use_ksymtab, version; |
| + | struct stat statbuf; |
| + | |
| + | /* WARNING: was using realpath, but replaced by readlink to stop using |
| + | * lots of stack. But here it seems to be able to cause problems? */ |
| + | absolute_filename = xmalloc_readlink(filename); |
| + | if (!absolute_filename) |
| absolute_filename = xstrdup(filename); |
| - | } |
| |
| lm_name = strlen(m_name); |
| lfilename = strlen(absolute_filename); |
| @@ -3791,22 +3735,22 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, |
| * is 0xffffff, decimal 16777215. putting all three fields in |
| * one symbol is less readable but saves kernel space. |
| */ |
| - | l = sizeof(symprefix)+ /* "__insmod_" */ |
| - | lm_name+ /* module name */ |
| - | 2+ /* "_O" */ |
| - | lfilename+ /* object filename */ |
| - | 2+ /* "_M" */ |
| - | 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ |
| - | 2+ /* "_V" */ |
| - | 8+ /* version in dec */ |
| - | 1; /* nul */ |
| + | l = sizeof(symprefix) + /* "__insmod_" */ |
| + | lm_name + /* module name */ |
| + | 2 + /* "_O" */ |
| + | lfilename + /* object filename */ |
| + | 2 + /* "_M" */ |
| + | 2 * sizeof(statbuf.st_mtime) + /* mtime in hex */ |
| + | 2 + /* "_V" */ |
| + | 8 + /* version in dec */ |
| + | 1; /* nul */ |
| name = xmalloc(l); |
| if (stat(absolute_filename, &statbuf) != 0) |
| statbuf.st_mtime = 0; |
| version = get_module_version(f, str); /* -1 if not found */ |
| snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", |
| symprefix, m_name, absolute_filename, |
| - | (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, |
| + | (int)(2 * sizeof(statbuf.st_mtime)), statbuf.st_mtime, |
| version); |
| sym = obj_add_symbol(f, name, -1, |
| ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), |
| @@ -3819,11 +3763,11 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, |
| /* record where the persistent data is going, same address as previous symbol */ |
| |
| if (f->persist) { |
| - | l = sizeof(symprefix)+ /* "__insmod_" */ |
| - | lm_name+ /* module name */ |
| - | 2+ /* "_P" */ |
| - | strlen(f->persist)+ /* data store */ |
| - | 1; /* nul */ |
| + | l = sizeof(symprefix) + /* "__insmod_" */ |
| + | lm_name + /* module name */ |
| + | 2 + /* "_P" */ |
| + | strlen(f->persist) + /* data store */ |
| + | 1; /* nul */ |
| name = xmalloc(l); |
| snprintf(name, l, "%s%s_P%s", |
| symprefix, m_name, f->persist); |
| @@ -3838,13 +3782,13 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, |
| for (i = 0; i < ARRAY_SIZE(section_names); ++i) { |
| sec = obj_find_section(f, section_names[i]); |
| if (sec && sec->header.sh_size) { |
| - | l = sizeof(symprefix)+ /* "__insmod_" */ |
| - | lm_name+ /* module name */ |
| - | 2+ /* "_S" */ |
| - | strlen(sec->name)+ /* section name */ |
| - | 2+ /* "_L" */ |
| - | 8+ /* length in dec */ |
| - | 1; /* nul */ |
| + | l = sizeof(symprefix) + /* "__insmod_" */ |
| + | lm_name + /* module name */ |
| + | 2 + /* "_S" */ |
| + | strlen(sec->name) + /* section name */ |
| + | 2 + /* "_L" */ |
| + | 8 + /* length in dec */ |
| + | 1; /* nul */ |
| name = xmalloc(l); |
| snprintf(name, l, "%s%s_S%s_L%ld", |
| symprefix, m_name, sec->name, |
| @@ -3891,9 +3835,10 @@ static void print_load_map(struct obj_file *f) |
| #if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL |
| /* Quick reference which section indicies are loaded. */ |
| |
| - | loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); |
| + | i = f->header.e_shnum; |
| + | loaded = alloca(sizeof(int) * i); |
| while (--i >= 0) |
| - | loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; |
| + | loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0); |
| |
| /* Collect the symbols we'll be listing. */ |
| |
| @@ -3963,7 +3908,7 @@ int insmod_main(int argc, char **argv) |
| ElfW(Addr) m_addr; |
| struct obj_file *f; |
| struct stat st; |
| - | char *m_name = 0; |
| + | char *m_name = NULL; |
| int exit_status = EXIT_FAILURE; |
| int m_has_modinfo; |
| #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING |
| @@ -4027,7 +3972,7 @@ int insmod_main(int argc, char **argv) |
| m_name = tmp; |
| } else { |
| free(tmp1); |
| - | tmp1 = 0; /* flag for free(m_name) before exit() */ |
| + | tmp1 = NULL; /* flag for free(m_name) before exit() */ |
| } |
| |
| /* Get a filedesc for the module. Check that we have a complete path */ |
| @@ -4039,7 +3984,6 @@ int insmod_main(int argc, char **argv) |
| if (k_version) { /* uname succeedd */ |
| char *module_dir; |
| char *tmdn; |
| - | char real_module_dir[FILENAME_MAX]; |
| |
| tmdn = concat_path_file(_PATH_MODULES, myuname.release); |
| /* Jump through hoops in case /lib/modules/`uname -r` |
| @@ -4047,36 +3991,37 @@ int insmod_main(int argc, char **argv) |
| * follow symlinks, but we do want to follow the |
| * /lib/modules/`uname -r` dir, So resolve it ourselves |
| * if it is a link... */ |
| - | if (realpath(tmdn, real_module_dir) == NULL) |
| - | module_dir = tmdn; |
| - | else |
| - | module_dir = real_module_dir; |
| + | module_dir = xmalloc_readlink(tmdn); |
| + | if (!module_dir) |
| + | module_dir = xstrdup(tmdn); |
| recursive_action(module_dir, ACTION_RECURSE, |
| - | check_module_name_match, 0, m_fullName, 0); |
| + | check_module_name_match, NULL, m_fullName, 0); |
| + | free(module_dir); |
| free(tmdn); |
| } |
| |
| /* Check if we have found anything yet */ |
| if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) { |
| - | char module_dir[FILENAME_MAX]; |
| + | int r; |
| + | char *module_dir; |
| |
| free(m_filename); |
| m_filename = NULL; |
| - | if (realpath(_PATH_MODULES, module_dir) == NULL) |
| - | strcpy(module_dir, _PATH_MODULES); |
| + | module_dir = xmalloc_readlink(_PATH_MODULES); |
| + | if (!module_dir) |
| + | module_dir = xstrdup(_PATH_MODULES); |
| /* No module found under /lib/modules/`uname -r`, this |
| * time cast the net a bit wider. Search /lib/modules/ */ |
| - | if (!recursive_action(module_dir, ACTION_RECURSE, |
| - | check_module_name_match, 0, m_fullName, 0) |
| + | r = recursive_action(module_dir, ACTION_RECURSE, |
| + | check_module_name_match, NULL, m_fullName, 0); |
| + | if (r) |
| + | bb_error_msg_and_die("%s: module not found", m_fullName); |
| + | free(module_dir); |
| + | if (m_filename == NULL |
| + | || ((fp = fopen(m_filename, "r")) == NULL) |
| ) { |
| - | if (m_filename == 0 |
| - | || ((fp = fopen(m_filename, "r")) == NULL) |
| - | ) { |
| - | bb_error_msg("%s: module not found", m_fullName); |
| - | goto out; |
| - | } |
| - | } else |
| bb_error_msg_and_die("%s: module not found", m_fullName); |
| + | } |
| } |
| } else |
| m_filename = xstrdup(arg1); |
| @@ -4093,8 +4038,6 @@ int insmod_main(int argc, char **argv) |
| #endif |
| |
| f = obj_load(fp, LOADBITS); |
| - | if (f == NULL) |
| - | bb_perror_msg_and_die("cannot load the module"); |
| |
| if (get_modinfo_value(f, "kernel_version") == NULL) |
| m_has_modinfo = 0; |
| @@ -4109,9 +4052,8 @@ int insmod_main(int argc, char **argv) |
| if (m_has_modinfo) { |
| m_version = new_get_module_version(f, m_strversion); |
| if (m_version == -1) { |
| - | bb_error_msg("cannot find the kernel version the module was " |
| + | bb_error_msg_and_die("cannot find the kernel version the module was " |
| "compiled for"); |
| - | goto out; |
| } |
| } |
| |
| @@ -4128,14 +4070,10 @@ int insmod_main(int argc, char **argv) |
| k_crcs = 0; |
| #endif /* FEATURE_INSMOD_VERSION_CHECKING */ |
| |
| - | if (!query_module(NULL, 0, NULL, 0, NULL)) { |
| - | if (!new_get_kernel_symbols()) |
| - | goto out; |
| - | k_crcs = new_is_kernel_checksummed(); |
| - | } else { |
| - | bb_error_msg("not configured to support old kernels"); |
| - | goto out; |
| - | } |
| + | if (query_module(NULL, 0, NULL, 0, NULL)) |
| + | bb_error_msg_and_die("not configured to support old kernels"); |
| + | new_get_kernel_symbols(); |
| + | k_crcs = new_is_kernel_checksummed(); |
| |
| #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING |
| m_crcs = 0; |
| @@ -4151,22 +4089,15 @@ int insmod_main(int argc, char **argv) |
| |
| /* Allocate common symbols, symbol tables, and string tables. */ |
| |
| - | if (!new_create_this_module(f, m_name)) { |
| - | goto out; |
| - | } |
| - | |
| - | if (!obj_check_undefineds(f)) { |
| - | goto out; |
| - | } |
| + | new_create_this_module(f, m_name); |
| + | obj_check_undefineds(f); |
| obj_allocate_commons(f); |
| check_tainted_module(f, m_name); |
| |
| /* done with the module name, on to the optional var=value arguments */ |
| ++optind; |
| if (optind < argc) { |
| - | if (!new_process_module_arguments(f, argc - optind, argv + optind)) { |
| - | goto out; |
| - | } |
| + | new_process_module_arguments(f, argc - optind, argv + optind); |
| } |
| |
| arch_create_got(f); |
| @@ -4181,22 +4112,18 @@ int insmod_main(int argc, char **argv) |
| /* Find current size of the module */ |
| m_size = obj_load_size(f); |
| |
| - | |
| m_addr = create_module(m_name, m_size); |
| if (m_addr == -1) switch (errno) { |
| case EEXIST: |
| - | bb_error_msg("a module named %s already exists", m_name); |
| - | goto out; |
| + | bb_error_msg_and_die("a module named %s already exists", m_name); |
| case ENOMEM: |
| - | bb_error_msg("can't allocate kernel memory for module; needed %lu bytes", |
| + | bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes", |
| m_size); |
| - | goto out; |
| default: |
| - | bb_perror_msg("create_module: %s", m_name); |
| - | goto out; |
| + | bb_perror_msg_and_die("create_module: %s", m_name); |
| } |
| |
| - | #if !LOADBITS |
| + | #if !LOADBITS |
| /* |
| * the PROGBITS section was not loaded by the obj_load |
| * now we can load them directly into the kernel memory |
| @@ -4222,7 +4149,7 @@ int insmod_main(int argc, char **argv) |
| |
| exit_status = EXIT_SUCCESS; |
| |
| - | out: |
| + | out: |
| #if ENABLE_FEATURE_CLEAN_UP |
| if (fp) |
| fclose(fp); |
| @@ -4234,8 +4161,10 @@ out: |
| return exit_status; |
| } |
| |
| - | |
| - | #endif |
| + | #endif /* ENABLE_FEATURE_2_4_MODULES */ |
| + | /* |
| + | * End of big piece of 2.4-specific code |
| + | */ |
| |
| |
| #if ENABLE_FEATURE_2_6_MODULES |
| @@ -4249,20 +4178,24 @@ static const char *moderror(int err) |
| { |
| switch (err) { |
| case ENOEXEC: |
| - | return "Invalid module format"; |
| + | return "invalid module format"; |
| case ENOENT: |
| - | return "Unknown symbol in module"; |
| + | return "unknown symbol in module"; |
| case ESRCH: |
| - | return "Module has wrong symbol version"; |
| + | return "module has wrong symbol version"; |
| case EINVAL: |
| - | return "Invalid parameters"; |
| + | return "invalid parameters"; |
| default: |
| return strerror(err); |
| } |
| } |
| |
| - | int insmod_ng_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| - | int insmod_ng_main(int argc, char **argv) |
| + | #if !ENABLE_FEATURE_2_4_MODULES |
| + | int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| + | int insmod_main(int argc, char **argv) |
| + | #else |
| + | static int insmod_ng_main(int argc, char **argv) |
| + | #endif |
| { |
| long ret; |
| size_t len; |