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