diff options
Diffstat (limited to 'modutils/insmod.c')
-rw-r--r-- | modutils/insmod.c | 411 |
1 files changed, 172 insertions, 239 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c index 6f3b7d0..df75abb 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c @@ -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; |