module: verify_export_symbols under the lock

It disabled preempt so it was "safe", but nothing stops another module
slipping in before this module is added to the global list now we don't
hold the lock the whole time.

So we check this just after we check for duplicate modules, and just
before we put the module in the global list.

(find_symbol finds symbols in coming and going modules, too).

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

+10 -16
+10 -16
kernel/module.c
··· 1571 1571 /* 1572 1572 * Ensure that an exported symbol [global namespace] does not already exist 1573 1573 * in the kernel or in some other module's exported symbol table. 1574 + * 1575 + * You must hold the module_mutex. 1574 1576 */ 1575 1577 static int verify_export_symbols(struct module *mod) 1576 1578 { ··· 1594 1592 1595 1593 for (i = 0; i < ARRAY_SIZE(arr); i++) { 1596 1594 for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) { 1597 - const struct kernel_symbol *sym; 1598 - 1599 - /* Stopping preemption makes find_symbol safe. */ 1600 - preempt_disable(); 1601 - sym = find_symbol(s->name, &owner, NULL, true, false); 1602 - preempt_enable(); 1603 - 1604 - if (sym) { 1595 + if (find_symbol(s->name, &owner, NULL, true, false)) { 1605 1596 printk(KERN_ERR 1606 1597 "%s: exports duplicate symbol %s" 1607 1598 " (owned by %s)\n", ··· 2435 2440 goto cleanup; 2436 2441 } 2437 2442 2438 - /* Find duplicate symbols */ 2439 - err = verify_export_symbols(mod); 2440 - if (err < 0) 2441 - goto cleanup; 2442 - 2443 2443 /* Set up and sort exception table */ 2444 2444 mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table", 2445 2445 sizeof(*mod->extable), &mod->num_exentries); ··· 2496 2506 mutex_lock(&module_mutex); 2497 2507 if (find_module(mod->name)) { 2498 2508 err = -EEXIST; 2499 - /* This will also unlock the mutex */ 2500 - goto already_exists; 2509 + goto unlock; 2501 2510 } 2511 + 2512 + /* Find duplicate symbols */ 2513 + err = verify_export_symbols(mod); 2514 + if (err < 0) 2515 + goto unlock; 2502 2516 2503 2517 list_add_rcu(&mod->list, &modules); 2504 2518 mutex_unlock(&module_mutex); ··· 2530 2536 mutex_lock(&module_mutex); 2531 2537 /* Unlink carefully: kallsyms could be walking list. */ 2532 2538 list_del_rcu(&mod->list); 2533 - already_exists: 2539 + unlock: 2534 2540 mutex_unlock(&module_mutex); 2535 2541 synchronize_sched(); 2536 2542 module_arch_cleanup(mod);