470-insmod_search.patch 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. --- a/modutils/insmod.c
  2. +++ b/modutils/insmod.c
  3. @@ -61,21 +61,117 @@
  4. #include "libbb.h"
  5. #include <libgen.h>
  6. #include <sys/utsname.h>
  7. +#if ENABLE_FEATURE_2_6_MODULES
  8. +#include <sys/mman.h>
  9. +#include <asm/unistd.h>
  10. +#include <sys/syscall.h>
  11. +#endif
  12. #if !ENABLE_FEATURE_2_4_MODULES && !ENABLE_FEATURE_2_6_MODULES
  13. #undef ENABLE_FEATURE_2_4_MODULES
  14. #define ENABLE_FEATURE_2_4_MODULES 1
  15. #endif
  16. -/*
  17. - * Big piece of 2.4-specific code
  18. - */
  19. #if ENABLE_FEATURE_2_4_MODULES
  20. -
  21. +int insmod_main_24(int argc, char **argv);
  22. +#endif
  23. #if ENABLE_FEATURE_2_6_MODULES
  24. -static int insmod_ng_main(int argc, char **argv);
  25. +int insmod_main_26(int argc, char **argv);
  26. #endif
  27. +int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  28. +static char *g_filename = NULL;
  29. +#define _PATH_MODULES "/lib/modules"
  30. +
  31. +static int check_module_name_match(const char *filename, struct stat *statbuf,
  32. + void *userdata, int depth)
  33. +{
  34. + char *fullname = (char *) userdata;
  35. + char *tmp;
  36. +
  37. + if (fullname[0] == '\0')
  38. + return FALSE;
  39. +
  40. + tmp = bb_get_last_path_component_nostrip(filename);
  41. + if (strcmp(tmp, fullname) == 0) {
  42. + /* Stop searching if we find a match */
  43. + g_filename = xstrdup(filename);
  44. + return FALSE;
  45. + }
  46. +
  47. + return TRUE;
  48. +}
  49. +
  50. +static int find_module(char *filename)
  51. +{
  52. + char *module_dir, real_module_dir[FILENAME_MAX];
  53. + int len, slen, ret = ENOENT, k_version;
  54. + struct utsname myuname;
  55. + const char *suffix;
  56. + struct stat st;
  57. +
  58. + /* check the kernel version */
  59. + if ((uname(&myuname) != 0) || (myuname.release[0] != '2'))
  60. + return EINVAL;
  61. +
  62. + k_version = myuname.release[2] - '0';
  63. +#if ENABLE_FEATURE_2_4_MODULES
  64. + if (k_version <= 4)
  65. + suffix = ".o";
  66. + else
  67. +#endif
  68. + suffix = ".ko";
  69. +
  70. + len = strlen(filename);
  71. + slen = strlen(suffix);
  72. +
  73. + /* check for suffix and absolute path first */
  74. + if ((len < slen + 2) || (strcmp(filename + len - slen, suffix) != 0)) {
  75. + filename = xasprintf("%s%s", filename, suffix);
  76. + } else {
  77. + filename = strdup(filename);
  78. + if ((stat(filename, &st) == 0) && S_ISREG(st.st_mode)) {
  79. + g_filename = filename;
  80. + return 0;
  81. + }
  82. + free(filename);
  83. + return ENOENT;
  84. + }
  85. +
  86. + /* next: scan /lib/modules/<release> */
  87. + /* Jump through hoops in case /lib/modules/`uname -r`
  88. + * is a symlink. We do not want recursive_action to
  89. + * follow symlinks, but we do want to follow the
  90. + * /lib/modules/`uname -r` dir, So resolve it ourselves
  91. + * if it is a link... */
  92. + module_dir = concat_path_file(_PATH_MODULES, myuname.release);
  93. + if (realpath(module_dir, real_module_dir) != NULL) {
  94. + free(module_dir);
  95. + module_dir = real_module_dir;
  96. + }
  97. +
  98. + recursive_action(module_dir, ACTION_RECURSE,
  99. + check_module_name_match, 0, filename, 0);
  100. +
  101. + /* Check if we have a complete path */
  102. + if (g_filename == NULL)
  103. + goto done;
  104. +
  105. + if ((stat(g_filename, &st) == 0) && S_ISREG(st.st_mode))
  106. + ret = 0;
  107. + else
  108. + free(g_filename);
  109. +
  110. +done:
  111. + free(filename);
  112. +
  113. + return ret;
  114. +}
  115. +
  116. +/*
  117. + * Big piece of 2.4-specific code
  118. + */
  119. +#if ENABLE_FEATURE_2_4_MODULES
  120. #if ENABLE_FEATURE_INSMOD_LOADINKMEM
  121. #define LOADBITS 0
  122. #else
  123. @@ -184,7 +280,6 @@ static int insmod_ng_main(int argc, char
  124. /* Microblaze */
  125. #if defined(__microblaze__)
  126. #define USE_SINGLE
  127. -#include <linux/elf-em.h>
  128. #define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
  129. #define SHT_RELM SHT_RELA
  130. #define Elf32_RelM Elf32_Rela
  131. @@ -452,7 +547,7 @@ enum {
  132. /* The system calls unchanged between 2.0 and 2.1. */
  133. unsigned long create_module(const char *, size_t);
  134. -int delete_module(const char *module, unsigned int flags);
  135. +int delete_module(const char *);
  136. #endif /* module.h */
  137. @@ -652,7 +747,7 @@ static struct obj_symbol *arch_new_symbo
  138. static enum obj_reloc arch_apply_relocation(struct obj_file *f,
  139. struct obj_section *targsec,
  140. - /*struct obj_section *symsec,*/
  141. + struct obj_section *symsec,
  142. struct obj_symbol *sym,
  143. ElfW(RelM) *rel, ElfW(Addr) value);
  144. @@ -673,6 +768,7 @@ static int obj_gpl_license(struct obj_fi
  145. #define SPFX ""
  146. #endif
  147. +
  148. enum { STRVERSIONLEN = 64 };
  149. /*======================================================================*/
  150. @@ -788,28 +884,6 @@ static char *m_filename;
  151. static char *m_fullName;
  152. -/*======================================================================*/
  153. -
  154. -
  155. -static int check_module_name_match(const char *filename,
  156. - struct stat *statbuf ATTRIBUTE_UNUSED,
  157. - void *userdata, int depth ATTRIBUTE_UNUSED)
  158. -{
  159. - char *fullname = (char *) userdata;
  160. - char *tmp;
  161. -
  162. - if (fullname[0] == '\0')
  163. - return FALSE;
  164. -
  165. - tmp = bb_get_last_path_component_nostrip(filename);
  166. - if (strcmp(tmp, fullname) == 0) {
  167. - /* Stop searching if we find a match */
  168. - m_filename = xstrdup(filename);
  169. - return FALSE;
  170. - }
  171. - return TRUE;
  172. -}
  173. -
  174. /*======================================================================*/
  175. @@ -835,32 +909,20 @@ static struct obj_symbol *arch_new_symbo
  176. static enum obj_reloc
  177. arch_apply_relocation(struct obj_file *f,
  178. struct obj_section *targsec,
  179. - /*struct obj_section *symsec,*/
  180. + struct obj_section *symsec,
  181. struct obj_symbol *sym,
  182. ElfW(RelM) *rel, ElfW(Addr) v)
  183. {
  184. -#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
  185. - || defined(__sh__) || defined(__s390__) || defined(__x86_64__) \
  186. - || defined(__powerpc__) || defined(__mips__)
  187. struct arch_file *ifile = (struct arch_file *) f;
  188. -#endif
  189. enum obj_reloc ret = obj_reloc_ok;
  190. ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
  191. -#if defined(__arm__) || defined(__H8300H__) || defined(__H8300S__) \
  192. - || defined(__i386__) || defined(__mc68000__) || defined(__microblaze__) \
  193. - || defined(__mips__) || defined(__nios2__) || defined(__powerpc__) \
  194. - || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
  195. ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
  196. -#endif
  197. #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
  198. struct arch_symbol *isym = (struct arch_symbol *) sym;
  199. #endif
  200. -#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
  201. - || defined(__sh__) || defined(__s390__)
  202. #if defined(USE_GOT_ENTRIES)
  203. ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
  204. #endif
  205. -#endif
  206. #if defined(USE_PLT_ENTRIES)
  207. ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
  208. unsigned long *ip;
  209. @@ -954,7 +1016,6 @@ arch_apply_relocation(struct obj_file *f
  210. case R_386_PLT32:
  211. case R_386_PC32:
  212. - case R_386_GOTOFF:
  213. *loc += v - dot;
  214. break;
  215. @@ -973,6 +1034,9 @@ arch_apply_relocation(struct obj_file *f
  216. case R_386_GOT32:
  217. goto bb_use_got;
  218. +
  219. + case R_386_GOTOFF:
  220. + *loc += v - got;
  221. break;
  222. #elif defined(__microblaze__)
  223. @@ -1759,7 +1823,7 @@ static int arch_list_add(ElfW(RelM) *rel
  224. #if defined(USE_SINGLE)
  225. -static int arch_single_init(/*ElfW(RelM) *rel,*/ struct arch_single_entry *single,
  226. +static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
  227. int offset, int size)
  228. {
  229. if (single->allocated == 0) {
  230. @@ -1907,7 +1971,7 @@ static void arch_create_got(struct obj_f
  231. #if defined(USE_GOT_ENTRIES)
  232. if (got_allocate) {
  233. got_offset += arch_single_init(
  234. - /*rel,*/ &intsym->gotent,
  235. + rel, &intsym->gotent,
  236. got_offset, GOT_ENTRY_SIZE);
  237. got_needed = 1;
  238. @@ -1921,7 +1985,7 @@ static void arch_create_got(struct obj_f
  239. plt_offset, PLT_ENTRY_SIZE);
  240. #else
  241. plt_offset += arch_single_init(
  242. - /*rel,*/ &intsym->pltent,
  243. + rel, &intsym->pltent,
  244. plt_offset, PLT_ENTRY_SIZE);
  245. #endif
  246. plt_needed = 1;
  247. @@ -1959,8 +2023,7 @@ static unsigned long obj_elf_hash_n(cons
  248. while (n > 0) {
  249. ch = *name++;
  250. h = (h << 4) + ch;
  251. - g = (h & 0xf0000000);
  252. - if (g != 0) {
  253. + if ((g = (h & 0xf0000000)) != 0) {
  254. h ^= g >> 24;
  255. h &= ~g;
  256. }
  257. @@ -2039,7 +2102,7 @@ obj_add_symbol(struct obj_file *f, const
  258. int n_type = ELF_ST_TYPE(info);
  259. int n_binding = ELF_ST_BIND(info);
  260. - for (sym = f->symtab[hash]; sym; sym = sym->next) {
  261. + for (sym = f->symtab[hash]; sym; sym = sym->next)
  262. if (f->symbol_cmp(sym->name, name) == 0) {
  263. int o_secidx = sym->secidx;
  264. int o_info = sym->info;
  265. @@ -2098,14 +2161,14 @@ obj_add_symbol(struct obj_file *f, const
  266. return sym;
  267. }
  268. }
  269. - }
  270. /* Completely new symbol. */
  271. sym = arch_new_symbol();
  272. sym->next = f->symtab[hash];
  273. f->symtab[hash] = sym;
  274. sym->ksymidx = -1;
  275. - if (ELF_ST_BIND(info) == STB_LOCAL && symidx != (unsigned long)(-1)) {
  276. +
  277. + if (ELF_ST_BIND(info) == STB_LOCAL && symidx != -1) {
  278. if (symidx >= f->local_symtab_size)
  279. bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
  280. name, (long) symidx, (long) f->local_symtab_size);
  281. @@ -3228,7 +3291,7 @@ static int obj_relocate(struct obj_file
  282. /* Do it! */
  283. switch (arch_apply_relocation
  284. - (f, targsec, /*symsec,*/ intsym, rel, value)
  285. + (f, targsec, symsec, intsym, rel, value)
  286. ) {
  287. case obj_reloc_ok:
  288. break;
  289. @@ -3307,11 +3370,11 @@ static int obj_create_image(struct obj_f
  290. /*======================================================================*/
  291. -static struct obj_file *obj_load(FILE * fp, int loadprogbits ATTRIBUTE_UNUSED)
  292. +static struct obj_file *obj_load(FILE * fp, int loadprogbits)
  293. {
  294. struct obj_file *f;
  295. ElfW(Shdr) * section_headers;
  296. - size_t shnum, i;
  297. + int shnum, i;
  298. char *shstrtab;
  299. /* Read the file header. */
  300. @@ -3583,7 +3646,7 @@ static int obj_gpl_license(struct obj_fi
  301. while (ptr < endptr) {
  302. value = strchr(ptr, '=');
  303. if (value && strncmp(ptr, "license", value-ptr) == 0) {
  304. - unsigned i;
  305. + int i;
  306. if (license)
  307. *license = value+1;
  308. for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) {
  309. @@ -3687,9 +3750,6 @@ static void check_tainted_module(struct
  310. * start of some sections. this info is used by ksymoops to do better
  311. * debugging.
  312. */
  313. -#if !ENABLE_FEATURE_INSMOD_VERSION_CHECKING
  314. -#define get_module_version(f, str) get_module_version(str)
  315. -#endif
  316. static int
  317. get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
  318. {
  319. @@ -3722,8 +3782,7 @@ add_ksymoops_symbols(struct obj_file *f,
  320. struct obj_symbol *sym;
  321. char *name, *absolute_filename;
  322. char str[STRVERSIONLEN];
  323. - unsigned i;
  324. - int l, lm_name, lfilename, use_ksymtab, version;
  325. + int i, l, lm_name, lfilename, use_ksymtab, version;
  326. struct stat statbuf;
  327. /* WARNING: was using realpath, but replaced by readlink to stop using
  328. @@ -3910,145 +3969,57 @@ static void print_load_map(struct obj_fi
  329. void print_load_map(struct obj_file *f);
  330. #endif
  331. -int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  332. -int insmod_main(int argc, char **argv)
  333. +int insmod_main_24( int argc, char **argv)
  334. {
  335. char *opt_o, *arg1;
  336. - int len;
  337. int k_crcs;
  338. - char *tmp, *tmp1;
  339. unsigned long m_size;
  340. ElfW(Addr) m_addr;
  341. struct obj_file *f;
  342. - struct stat st;
  343. - char *m_name = NULL;
  344. - int exit_status = EXIT_FAILURE;
  345. + char *tmp = NULL, *m_name = NULL;
  346. + int ret = EINVAL;
  347. int m_has_modinfo;
  348. #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
  349. struct utsname uts_info;
  350. char m_strversion[STRVERSIONLEN];
  351. int m_version, m_crcs;
  352. #endif
  353. -#if ENABLE_FEATURE_CLEAN_UP
  354. FILE *fp = NULL;
  355. -#else
  356. - FILE *fp;
  357. -#endif
  358. - int k_version = 0;
  359. + int k_version;
  360. struct utsname myuname;
  361. + /* check the kernel version */
  362. + if ((uname(&myuname) != 0) || (myuname.release[0] != '2'))
  363. + return EINVAL;
  364. +
  365. + k_version = myuname.release[2] - '0';
  366. + if (k_version > 4)
  367. + return ENOTSUP;
  368. +
  369. /* Parse any options */
  370. getopt32(argv, OPTION_STR, &opt_o);
  371. arg1 = argv[optind];
  372. if (option_mask32 & OPT_o) { // -o /* name the output module */
  373. - free(m_name);
  374. m_name = xstrdup(opt_o);
  375. }
  376. - if (arg1 == NULL) {
  377. + if (arg1 == NULL)
  378. bb_show_usage();
  379. - }
  380. - /* Grab the module name */
  381. - tmp1 = xstrdup(arg1);
  382. - tmp = basename(tmp1);
  383. - len = strlen(tmp);
  384. -
  385. - if (uname(&myuname) == 0) {
  386. - if (myuname.release[0] == '2') {
  387. - k_version = myuname.release[2] - '0';
  388. - }
  389. - }
  390. -
  391. -#if ENABLE_FEATURE_2_6_MODULES
  392. - if (k_version > 4 && len > 3 && tmp[len - 3] == '.'
  393. - && tmp[len - 2] == 'k' && tmp[len - 1] == 'o'
  394. - ) {
  395. - len -= 3;
  396. - tmp[len] = '\0';
  397. - } else
  398. -#endif
  399. - if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
  400. - len -= 2;
  401. - tmp[len] = '\0';
  402. - }
  403. -
  404. -
  405. -#if ENABLE_FEATURE_2_6_MODULES
  406. - if (k_version > 4)
  407. - m_fullName = xasprintf("%s.ko", tmp);
  408. - else
  409. -#endif
  410. - m_fullName = xasprintf("%s.o", tmp);
  411. + ret = find_module(arg1);
  412. + if (ret)
  413. + goto out;
  414. if (!m_name) {
  415. - m_name = tmp;
  416. - } else {
  417. - free(tmp1);
  418. - tmp1 = NULL; /* flag for free(m_name) before exit() */
  419. - }
  420. -
  421. - /* Get a filedesc for the module. Check that we have a complete path */
  422. - if (stat(arg1, &st) < 0 || !S_ISREG(st.st_mode)
  423. - || (fp = fopen(arg1, "r")) == NULL
  424. - ) {
  425. - /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
  426. - * but do not error out yet if we fail to find it... */
  427. - if (k_version) { /* uname succeedd */
  428. - char *module_dir;
  429. - char *tmdn;
  430. -
  431. - tmdn = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, myuname.release);
  432. - /* Jump through hoops in case /lib/modules/`uname -r`
  433. - * is a symlink. We do not want recursive_action to
  434. - * follow symlinks, but we do want to follow the
  435. - * /lib/modules/`uname -r` dir, So resolve it ourselves
  436. - * if it is a link... */
  437. - module_dir = xmalloc_readlink(tmdn);
  438. - if (!module_dir)
  439. - module_dir = xstrdup(tmdn);
  440. - recursive_action(module_dir, ACTION_RECURSE,
  441. - check_module_name_match, NULL, m_fullName, 0);
  442. - free(module_dir);
  443. - free(tmdn);
  444. - }
  445. -
  446. - /* Check if we have found anything yet */
  447. - if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) {
  448. - int r;
  449. - char *module_dir;
  450. -
  451. - free(m_filename);
  452. - m_filename = NULL;
  453. - module_dir = xmalloc_readlink(CONFIG_DEFAULT_MODULES_DIR);
  454. - if (!module_dir)
  455. - module_dir = xstrdup(CONFIG_DEFAULT_MODULES_DIR);
  456. - /* No module found under /lib/modules/`uname -r`, this
  457. - * time cast the net a bit wider. Search /lib/modules/ */
  458. - r = recursive_action(module_dir, ACTION_RECURSE,
  459. - check_module_name_match, NULL, m_fullName, 0);
  460. - if (r)
  461. - bb_error_msg_and_die("%s: module not found", m_fullName);
  462. - free(module_dir);
  463. - if (m_filename == NULL
  464. - || ((fp = fopen(m_filename, "r")) == NULL)
  465. - ) {
  466. - bb_error_msg_and_die("%s: module not found", m_fullName);
  467. - }
  468. + tmp = xstrdup(arg1);
  469. + m_name = basename(tmp);
  470. }
  471. - } else
  472. - m_filename = xstrdup(arg1);
  473. - if (flag_verbose)
  474. - printf("Using %s\n", m_filename);
  475. -
  476. -#if ENABLE_FEATURE_2_6_MODULES
  477. - if (k_version > 4) {
  478. - argv[optind] = m_filename;
  479. - optind--;
  480. - return insmod_ng_main(argc - optind, argv + optind);
  481. + fp = fopen(g_filename, "r");
  482. + if (!fp) {
  483. + ret = errno;
  484. + goto out;
  485. }
  486. -#endif
  487. f = obj_load(fp, LOADBITS);
  488. @@ -4075,7 +4046,7 @@ int insmod_main(int argc, char **argv)
  489. "\t%s was compiled for kernel version %s\n"
  490. "\twhile this kernel is version %s",
  491. flag_force_load ? "warning: " : "",
  492. - m_filename, m_strversion, uts_info.release);
  493. + g_filename, m_strversion, uts_info.release);
  494. if (!flag_force_load)
  495. goto out;
  496. }
  497. @@ -4117,7 +4088,7 @@ int insmod_main(int argc, char **argv)
  498. hide_special_symbols(f);
  499. #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
  500. - add_ksymoops_symbols(f, m_filename, m_name);
  501. + add_ksymoops_symbols(f, g_filename, m_name);
  502. #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
  503. new_create_module_ksymtab(f);
  504. @@ -4126,7 +4097,7 @@ int insmod_main(int argc, char **argv)
  505. m_size = obj_load_size(f);
  506. m_addr = create_module(m_name, m_size);
  507. - if (m_addr == (ElfW(Addr))(-1)) switch (errno) {
  508. + if (m_addr == -1) switch (errno) {
  509. case EEXIST:
  510. bb_error_msg_and_die("a module named %s already exists", m_name);
  511. case ENOMEM:
  512. @@ -4142,36 +4113,37 @@ int insmod_main(int argc, char **argv)
  513. * now we can load them directly into the kernel memory
  514. */
  515. if (!obj_load_progbits(fp, f, (char*)m_addr)) {
  516. - delete_module(m_name, 0);
  517. + delete_module(m_name);
  518. goto out;
  519. }
  520. #endif
  521. if (!obj_relocate(f, m_addr)) {
  522. - delete_module(m_name, 0);
  523. + delete_module(m_name);
  524. goto out;
  525. }
  526. if (!new_init_module(m_name, f, m_size)) {
  527. - delete_module(m_name, 0);
  528. + delete_module(m_name);
  529. goto out;
  530. }
  531. if (flag_print_load_map)
  532. print_load_map(f);
  533. - exit_status = EXIT_SUCCESS;
  534. + ret = EXIT_SUCCESS;
  535. out:
  536. #if ENABLE_FEATURE_CLEAN_UP
  537. if (fp)
  538. fclose(fp);
  539. - free(tmp1);
  540. - if (!tmp1)
  541. + if (tmp)
  542. + free(tmp);
  543. + else if (m_name)
  544. free(m_name);
  545. - free(m_filename);
  546. + free(g_filename);
  547. #endif
  548. - return exit_status;
  549. + return ret;
  550. }
  551. #endif /* ENABLE_FEATURE_2_4_MODULES */
  552. @@ -4183,15 +4155,8 @@ int insmod_main(int argc, char **argv)
  553. #if ENABLE_FEATURE_2_6_MODULES
  554. #include <sys/mman.h>
  555. -
  556. -#if defined __UCLIBC__ && !ENABLE_FEATURE_2_4_MODULES
  557. -/* big time suckage. The old prototype above renders our nice fwd-decl wrong */
  558. -extern int init_module(void *module, unsigned long len, const char *options);
  559. -#else
  560. #include <asm/unistd.h>
  561. #include <sys/syscall.h>
  562. -#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
  563. -#endif
  564. /* We use error numbers in a loose translation... */
  565. static const char *moderror(int err)
  566. @@ -4210,22 +4175,32 @@ static const char *moderror(int err)
  567. }
  568. }
  569. -#if !ENABLE_FEATURE_2_4_MODULES
  570. -int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  571. -int insmod_main(int argc ATTRIBUTE_UNUSED, char **argv)
  572. -#else
  573. -static int insmod_ng_main(int argc ATTRIBUTE_UNUSED, char **argv)
  574. -#endif
  575. +int insmod_main_26(int argc, char **argv)
  576. {
  577. - size_t len;
  578. + char *filename, *options;
  579. + struct utsname myuname;
  580. + int k_version;
  581. int optlen;
  582. + size_t len;
  583. void *map;
  584. - char *filename, *options;
  585. + long ret = 0;
  586. +
  587. + /* check the kernel version */
  588. + if ((uname(&myuname) != 0) || (myuname.release[0] != '2'))
  589. + return EINVAL;
  590. +
  591. + k_version = myuname.release[2] - '0';
  592. + if (k_version <= 4)
  593. + return ENOTSUP;
  594. filename = *++argv;
  595. if (!filename)
  596. bb_show_usage();
  597. + ret = find_module(filename);
  598. + if (ret || (g_filename == NULL))
  599. + goto done;
  600. +
  601. /* Rest is options */
  602. options = xzalloc(1);
  603. optlen = 0;
  604. @@ -4235,41 +4210,47 @@ static int insmod_ng_main(int argc ATTRI
  605. optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv);
  606. }
  607. -#if 0
  608. - /* Any special reason why mmap? It isn't performance critical. -vda */
  609. - /* Yes, xmalloc'ing can use *alot* of RAM. Don't forget that there are
  610. - * modules out there that are half a megabyte! mmap()ing is way nicer
  611. - * for small mem boxes, i guess. */
  612. - /* But after load, these modules will take up that 0.5mb in kernel
  613. - * anyway. Using malloc here causes only a transient spike to 1mb,
  614. - * after module is loaded, we go back to normal 0.5mb usage
  615. - * (in kernel). Also, mmap isn't magic - when we touch mapped data,
  616. - * we use memory. -vda */
  617. - int fd;
  618. - struct stat st;
  619. - unsigned long len;
  620. - fd = xopen(filename, O_RDONLY);
  621. - fstat(fd, &st);
  622. - len = st.st_size;
  623. - map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
  624. - if (map == MAP_FAILED) {
  625. - bb_perror_msg_and_die("cannot mmap '%s'", filename);
  626. - }
  627. -
  628. - /* map == NULL on Blackfin, probably on other MMU-less systems too. Workaround. */
  629. - if (map == NULL) {
  630. - map = xmalloc(len);
  631. - xread(fd, map, len);
  632. - }
  633. -#else
  634. len = MAXINT(ssize_t);
  635. - map = xmalloc_open_read_close(filename, &len);
  636. -#endif
  637. + map = xmalloc_open_read_close(g_filename, &len);
  638. + ret = syscall(__NR_init_module, map, len, options);
  639. + if (ret != 0) {
  640. + bb_perror_msg_and_die("cannot insert '%s': %s (%li)",
  641. + g_filename, moderror(errno), ret);
  642. + }
  643. +done:
  644. + if (g_filename && (g_filename != filename))
  645. + free(g_filename);
  646. - if (init_module(map, len, options) != 0)
  647. - bb_error_msg_and_die("cannot insert '%s': %s",
  648. - filename, moderror(errno));
  649. - return 0;
  650. + return ret;
  651. }
  652. #endif
  653. +
  654. +int insmod_main(int argc, char **argv)
  655. +{
  656. + int ret;
  657. +
  658. + g_filename = NULL;
  659. +#if ENABLE_FEATURE_2_6_MODULES
  660. + ret = insmod_main_26(argc, argv);
  661. + if (ret != ENOTSUP)
  662. + goto done;
  663. +#endif
  664. +
  665. +#if ENABLE_FEATURE_2_4_MODULES
  666. + ret = insmod_main_24(argc, argv);
  667. + if (ret != ENOTSUP)
  668. + goto done;
  669. +#endif
  670. +
  671. + fprintf(stderr, "Error: Kernel version not supported\n");
  672. + return 1;
  673. +
  674. +done:
  675. + if (ret) {
  676. + errno = ret;
  677. + bb_perror_msg("Loading module failed");
  678. + return ret;
  679. + } else
  680. + return 0;
  681. +}