Commit 22e268ebecc549f1b1907f114cb44d6044bdee3c

Authored by Rusty Russell
1 parent 9f85a4bbb1

module: refactor load_module part 5

1) Extract out the relocation loop into apply_relocations
2) Extract license and version checks into check_module_license_and_versions
3) Extract icache flushing into flush_module_icache
4) Move __obsparm warning into find_module_sections
5) Move license setting into check_modinfo.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 1 changed file with 106 additions and 76 deletions Side-by-side Diff

... ... @@ -1698,6 +1698,39 @@
1698 1698 return ret;
1699 1699 }
1700 1700  
  1701 +static int apply_relocations(struct module *mod,
  1702 + Elf_Ehdr *hdr,
  1703 + Elf_Shdr *sechdrs,
  1704 + unsigned int symindex,
  1705 + unsigned int strindex)
  1706 +{
  1707 + unsigned int i;
  1708 + int err = 0;
  1709 +
  1710 + /* Now do relocations. */
  1711 + for (i = 1; i < hdr->e_shnum; i++) {
  1712 + const char *strtab = (char *)sechdrs[strindex].sh_addr;
  1713 + unsigned int info = sechdrs[i].sh_info;
  1714 +
  1715 + /* Not a valid relocation section? */
  1716 + if (info >= hdr->e_shnum)
  1717 + continue;
  1718 +
  1719 + /* Don't bother with non-allocated sections */
  1720 + if (!(sechdrs[info].sh_flags & SHF_ALLOC))
  1721 + continue;
  1722 +
  1723 + if (sechdrs[i].sh_type == SHT_REL)
  1724 + err = apply_relocate(sechdrs, strtab, symindex, i, mod);
  1725 + else if (sechdrs[i].sh_type == SHT_RELA)
  1726 + err = apply_relocate_add(sechdrs, strtab, symindex, i,
  1727 + mod);
  1728 + if (err < 0)
  1729 + break;
  1730 + }
  1731 + return err;
  1732 +}
  1733 +
1701 1734 /* Additional bytes needed by arch in front of individual sections */
1702 1735 unsigned int __weak arch_mod_section_prepend(struct module *mod,
1703 1736 unsigned int section)
... ... @@ -2179,6 +2212,10 @@
2179 2212 " the quality is unknown, you have been warned.\n",
2180 2213 mod->name);
2181 2214 }
  2215 +
  2216 + /* Set up license info based on the info section */
  2217 + set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
  2218 +
2182 2219 return 0;
2183 2220 }
2184 2221  
... ... @@ -2245,6 +2282,10 @@
2245 2282 sizeof(*mod->ftrace_callsites),
2246 2283 &mod->num_ftrace_callsites);
2247 2284 #endif
  2285 +
  2286 + if (section_addr(hdr, sechdrs, secstrings, "__obsparm"))
  2287 + printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
  2288 + mod->name);
2248 2289 }
2249 2290  
2250 2291 static struct module *move_module(struct module *mod,
... ... @@ -2311,6 +2352,60 @@
2311 2352 return mod;
2312 2353 }
2313 2354  
  2355 +static int check_module_license_and_versions(struct module *mod,
  2356 + Elf_Shdr *sechdrs)
  2357 +{
  2358 + /*
  2359 + * ndiswrapper is under GPL by itself, but loads proprietary modules.
  2360 + * Don't use add_taint_module(), as it would prevent ndiswrapper from
  2361 + * using GPL-only symbols it needs.
  2362 + */
  2363 + if (strcmp(mod->name, "ndiswrapper") == 0)
  2364 + add_taint(TAINT_PROPRIETARY_MODULE);
  2365 +
  2366 + /* driverloader was caught wrongly pretending to be under GPL */
  2367 + if (strcmp(mod->name, "driverloader") == 0)
  2368 + add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
  2369 +
  2370 +#ifdef CONFIG_MODVERSIONS
  2371 + if ((mod->num_syms && !mod->crcs)
  2372 + || (mod->num_gpl_syms && !mod->gpl_crcs)
  2373 + || (mod->num_gpl_future_syms && !mod->gpl_future_crcs)
  2374 +#ifdef CONFIG_UNUSED_SYMBOLS
  2375 + || (mod->num_unused_syms && !mod->unused_crcs)
  2376 + || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
  2377 +#endif
  2378 + ) {
  2379 + return try_to_force_load(mod,
  2380 + "no versions for exported symbols");
  2381 + }
  2382 +#endif
  2383 + return 0;
  2384 +}
  2385 +
  2386 +static void flush_module_icache(const struct module *mod)
  2387 +{
  2388 + mm_segment_t old_fs;
  2389 +
  2390 + /* flush the icache in correct context */
  2391 + old_fs = get_fs();
  2392 + set_fs(KERNEL_DS);
  2393 +
  2394 + /*
  2395 + * Flush the instruction cache, since we've played with text.
  2396 + * Do it before processing of module parameters, so the module
  2397 + * can provide parameter accessor functions of its own.
  2398 + */
  2399 + if (mod->module_init)
  2400 + flush_icache_range((unsigned long)mod->module_init,
  2401 + (unsigned long)mod->module_init
  2402 + + mod->init_size);
  2403 + flush_icache_range((unsigned long)mod->module_core,
  2404 + (unsigned long)mod->module_core + mod->core_size);
  2405 +
  2406 + set_fs(old_fs);
  2407 +}
  2408 +
2314 2409 /* Allocate and load the module: note that size of section 0 is always
2315 2410 zero, and we rely on this for optional sections. */
2316 2411 static noinline struct module *load_module(void __user *umod,
... ... @@ -2331,8 +2426,6 @@
2331 2426 struct _ddebug *debug = NULL;
2332 2427 unsigned int num_debug = 0;
2333 2428  
2334   - mm_segment_t old_fs;
2335   -
2336 2429 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
2337 2430 umod, len, uargs);
2338 2431  
2339 2432  
2340 2433  
... ... @@ -2453,21 +2546,14 @@
2453 2546 if (err)
2454 2547 goto free_init;
2455 2548  
2456   - /* Set up license info based on the info section */
2457   - set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
  2549 + /* Now we've got everything in the final locations, we can
  2550 + * find optional sections. */
  2551 + find_module_sections(mod, hdr, sechdrs, secstrings);
2458 2552  
2459   - /*
2460   - * ndiswrapper is under GPL by itself, but loads proprietary modules.
2461   - * Don't use add_taint_module(), as it would prevent ndiswrapper from
2462   - * using GPL-only symbols it needs.
2463   - */
2464   - if (strcmp(mod->name, "ndiswrapper") == 0)
2465   - add_taint(TAINT_PROPRIETARY_MODULE);
  2553 + err = check_module_license_and_versions(mod, sechdrs);
  2554 + if (err)
  2555 + goto free_unload;
2466 2556  
2467   - /* driverloader was caught wrongly pretending to be under GPL */
2468   - if (strcmp(mod->name, "driverloader") == 0)
2469   - add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
2470   -
2471 2557 /* Set up MODINFO_ATTR fields */
2472 2558 setup_modinfo(mod, sechdrs, infoindex);
2473 2559  
2474 2560  
... ... @@ -2477,48 +2563,10 @@
2477 2563 if (err < 0)
2478 2564 goto cleanup;
2479 2565  
2480   - /* Now we've got everything in the final locations, we can
2481   - * find optional sections. */
2482   - find_module_sections(mod, hdr, sechdrs, secstrings);
  2566 + err = apply_relocations(mod, hdr, sechdrs, symindex, strindex);
  2567 + if (err < 0)
  2568 + goto cleanup;
2483 2569  
2484   -#ifdef CONFIG_MODVERSIONS
2485   - if ((mod->num_syms && !mod->crcs)
2486   - || (mod->num_gpl_syms && !mod->gpl_crcs)
2487   - || (mod->num_gpl_future_syms && !mod->gpl_future_crcs)
2488   -#ifdef CONFIG_UNUSED_SYMBOLS
2489   - || (mod->num_unused_syms && !mod->unused_crcs)
2490   - || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
2491   -#endif
2492   - ) {
2493   - err = try_to_force_load(mod,
2494   - "no versions for exported symbols");
2495   - if (err)
2496   - goto cleanup;
2497   - }
2498   -#endif
2499   -
2500   - /* Now do relocations. */
2501   - for (i = 1; i < hdr->e_shnum; i++) {
2502   - const char *strtab = (char *)sechdrs[strindex].sh_addr;
2503   - unsigned int info = sechdrs[i].sh_info;
2504   -
2505   - /* Not a valid relocation section? */
2506   - if (info >= hdr->e_shnum)
2507   - continue;
2508   -
2509   - /* Don't bother with non-allocated sections */
2510   - if (!(sechdrs[info].sh_flags & SHF_ALLOC))
2511   - continue;
2512   -
2513   - if (sechdrs[i].sh_type == SHT_REL)
2514   - err = apply_relocate(sechdrs, strtab, symindex, i,mod);
2515   - else if (sechdrs[i].sh_type == SHT_RELA)
2516   - err = apply_relocate_add(sechdrs, strtab, symindex, i,
2517   - mod);
2518   - if (err < 0)
2519   - goto cleanup;
2520   - }
2521   -
2522 2570 /* Set up and sort exception table */
2523 2571 mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table",
2524 2572 sizeof(*mod->extable), &mod->num_exentries);
2525 2573  
2526 2574  
... ... @@ -2541,28 +2589,9 @@
2541 2589 if (err < 0)
2542 2590 goto cleanup;
2543 2591  
2544   - /* flush the icache in correct context */
2545   - old_fs = get_fs();
2546   - set_fs(KERNEL_DS);
  2592 + flush_module_icache(mod);
2547 2593  
2548   - /*
2549   - * Flush the instruction cache, since we've played with text.
2550   - * Do it before processing of module parameters, so the module
2551   - * can provide parameter accessor functions of its own.
2552   - */
2553   - if (mod->module_init)
2554   - flush_icache_range((unsigned long)mod->module_init,
2555   - (unsigned long)mod->module_init
2556   - + mod->init_size);
2557   - flush_icache_range((unsigned long)mod->module_core,
2558   - (unsigned long)mod->module_core + mod->core_size);
2559   -
2560   - set_fs(old_fs);
2561   -
2562 2594 mod->args = args;
2563   - if (section_addr(hdr, sechdrs, secstrings, "__obsparm"))
2564   - printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
2565   - mod->name);
2566 2595  
2567 2596 /* Now sew it into the lists so we can get lockdep and oops
2568 2597 * info during argument parsing. Noone should access us, since
... ... @@ -2619,6 +2648,7 @@
2619 2648 module_arch_cleanup(mod);
2620 2649 cleanup:
2621 2650 free_modinfo(mod);
  2651 + free_unload:
2622 2652 module_unload_free(mod);
2623 2653 free_init:
2624 2654 module_free(mod, mod->module_init);