aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-02-09 19:40:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-02-09 19:40:59 -0500
commit2178cbc68f3602dc0b5949b9be2c8383ad3d93ef (patch)
tree0ce16c588dfa2c4ba665f1a5265026a11fafa826
parent7cf91adc0d38eb6cc8517ae45126ca7440177e61 (diff)
parent8244062ef1e54502ef55f54cced659913f244c3e (diff)
Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module fixes from Rusty Russell: "Fix for async_probe module param added in 4.3 (clearly not widely used yet), and a much more interesting kallsyms race which has been around approximately forever. This fix is more invasive, and will require some care in backporting, but I hated all the bandaids I could think of, so... There are some more coming, which are only for breakages introduced this cycle (livepatch), but wanted these in now" * tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: modules: fix longstanding /proc/kallsyms vs module insertion race. module: wrapper for symbol name. modules: fix modparam async_probe request
-rw-r--r--include/linux/module.h19
-rw-r--r--kernel/module.c120
2 files changed, 85 insertions, 54 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 4560d8f1545d..2bb0c3085706 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -324,6 +324,12 @@ struct module_layout {
324#define __module_layout_align 324#define __module_layout_align
325#endif 325#endif
326 326
327struct mod_kallsyms {
328 Elf_Sym *symtab;
329 unsigned int num_symtab;
330 char *strtab;
331};
332
327struct module { 333struct module {
328 enum module_state state; 334 enum module_state state;
329 335
@@ -405,15 +411,10 @@ struct module {
405#endif 411#endif
406 412
407#ifdef CONFIG_KALLSYMS 413#ifdef CONFIG_KALLSYMS
408 /* 414 /* Protected by RCU and/or module_mutex: use rcu_dereference() */
409 * We keep the symbol and string tables for kallsyms. 415 struct mod_kallsyms *kallsyms;
410 * The core_* fields below are temporary, loader-only (they 416 struct mod_kallsyms core_kallsyms;
411 * could really be discarded after module init). 417
412 */
413 Elf_Sym *symtab, *core_symtab;
414 unsigned int num_symtab, core_num_syms;
415 char *strtab, *core_strtab;
416
417 /* Section attributes */ 418 /* Section attributes */
418 struct module_sect_attrs *sect_attrs; 419 struct module_sect_attrs *sect_attrs;
419 420
diff --git a/kernel/module.c b/kernel/module.c
index 8358f4697c0c..9537da37ce87 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -303,6 +303,9 @@ struct load_info {
303 struct _ddebug *debug; 303 struct _ddebug *debug;
304 unsigned int num_debug; 304 unsigned int num_debug;
305 bool sig_ok; 305 bool sig_ok;
306#ifdef CONFIG_KALLSYMS
307 unsigned long mod_kallsyms_init_off;
308#endif
306 struct { 309 struct {
307 unsigned int sym, str, mod, vers, info, pcpu; 310 unsigned int sym, str, mod, vers, info, pcpu;
308 } index; 311 } index;
@@ -2480,10 +2483,21 @@ static void layout_symtab(struct module *mod, struct load_info *info)
2480 strsect->sh_flags |= SHF_ALLOC; 2483 strsect->sh_flags |= SHF_ALLOC;
2481 strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect, 2484 strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect,
2482 info->index.str) | INIT_OFFSET_MASK; 2485 info->index.str) | INIT_OFFSET_MASK;
2483 mod->init_layout.size = debug_align(mod->init_layout.size);
2484 pr_debug("\t%s\n", info->secstrings + strsect->sh_name); 2486 pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
2487
2488 /* We'll tack temporary mod_kallsyms on the end. */
2489 mod->init_layout.size = ALIGN(mod->init_layout.size,
2490 __alignof__(struct mod_kallsyms));
2491 info->mod_kallsyms_init_off = mod->init_layout.size;
2492 mod->init_layout.size += sizeof(struct mod_kallsyms);
2493 mod->init_layout.size = debug_align(mod->init_layout.size);
2485} 2494}
2486 2495
2496/*
2497 * We use the full symtab and strtab which layout_symtab arranged to
2498 * be appended to the init section. Later we switch to the cut-down
2499 * core-only ones.
2500 */
2487static void add_kallsyms(struct module *mod, const struct load_info *info) 2501static void add_kallsyms(struct module *mod, const struct load_info *info)
2488{ 2502{
2489 unsigned int i, ndst; 2503 unsigned int i, ndst;
@@ -2492,29 +2506,34 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
2492 char *s; 2506 char *s;
2493 Elf_Shdr *symsec = &info->sechdrs[info->index.sym]; 2507 Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
2494 2508
2495 mod->symtab = (void *)symsec->sh_addr; 2509 /* Set up to point into init section. */
2496 mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym); 2510 mod->kallsyms = mod->init_layout.base + info->mod_kallsyms_init_off;
2511
2512 mod->kallsyms->symtab = (void *)symsec->sh_addr;
2513 mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
2497 /* Make sure we get permanent strtab: don't use info->strtab. */ 2514 /* Make sure we get permanent strtab: don't use info->strtab. */
2498 mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr; 2515 mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
2499 2516
2500 /* Set types up while we still have access to sections. */ 2517 /* Set types up while we still have access to sections. */
2501 for (i = 0; i < mod->num_symtab; i++) 2518 for (i = 0; i < mod->kallsyms->num_symtab; i++)
2502 mod->symtab[i].st_info = elf_type(&mod->symtab[i], info); 2519 mod->kallsyms->symtab[i].st_info
2503 2520 = elf_type(&mod->kallsyms->symtab[i], info);
2504 mod->core_symtab = dst = mod->core_layout.base + info->symoffs; 2521
2505 mod->core_strtab = s = mod->core_layout.base + info->stroffs; 2522 /* Now populate the cut down core kallsyms for after init. */
2506 src = mod->symtab; 2523 mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
2507 for (ndst = i = 0; i < mod->num_symtab; i++) { 2524 mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
2525 src = mod->kallsyms->symtab;
2526 for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
2508 if (i == 0 || 2527 if (i == 0 ||
2509 is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, 2528 is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
2510 info->index.pcpu)) { 2529 info->index.pcpu)) {
2511 dst[ndst] = src[i]; 2530 dst[ndst] = src[i];
2512 dst[ndst++].st_name = s - mod->core_strtab; 2531 dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
2513 s += strlcpy(s, &mod->strtab[src[i].st_name], 2532 s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
2514 KSYM_NAME_LEN) + 1; 2533 KSYM_NAME_LEN) + 1;
2515 } 2534 }
2516 } 2535 }
2517 mod->core_num_syms = ndst; 2536 mod->core_kallsyms.num_symtab = ndst;
2518} 2537}
2519#else 2538#else
2520static inline void layout_symtab(struct module *mod, struct load_info *info) 2539static inline void layout_symtab(struct module *mod, struct load_info *info)
@@ -3263,9 +3282,8 @@ static noinline int do_init_module(struct module *mod)
3263 module_put(mod); 3282 module_put(mod);
3264 trim_init_extable(mod); 3283 trim_init_extable(mod);
3265#ifdef CONFIG_KALLSYMS 3284#ifdef CONFIG_KALLSYMS
3266 mod->num_symtab = mod->core_num_syms; 3285 /* Switch to core kallsyms now init is done: kallsyms may be walking! */
3267 mod->symtab = mod->core_symtab; 3286 rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
3268 mod->strtab = mod->core_strtab;
3269#endif 3287#endif
3270 mod_tree_remove_init(mod); 3288 mod_tree_remove_init(mod);
3271 disable_ro_nx(&mod->init_layout); 3289 disable_ro_nx(&mod->init_layout);
@@ -3496,7 +3514,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
3496 3514
3497 /* Module is ready to execute: parsing args may do that. */ 3515 /* Module is ready to execute: parsing args may do that. */
3498 after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, 3516 after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
3499 -32768, 32767, NULL, 3517 -32768, 32767, mod,
3500 unknown_module_param_cb); 3518 unknown_module_param_cb);
3501 if (IS_ERR(after_dashes)) { 3519 if (IS_ERR(after_dashes)) {
3502 err = PTR_ERR(after_dashes); 3520 err = PTR_ERR(after_dashes);
@@ -3627,6 +3645,11 @@ static inline int is_arm_mapping_symbol(const char *str)
3627 && (str[2] == '\0' || str[2] == '.'); 3645 && (str[2] == '\0' || str[2] == '.');
3628} 3646}
3629 3647
3648static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
3649{
3650 return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
3651}
3652
3630static const char *get_ksymbol(struct module *mod, 3653static const char *get_ksymbol(struct module *mod,
3631 unsigned long addr, 3654 unsigned long addr,
3632 unsigned long *size, 3655 unsigned long *size,
@@ -3634,6 +3657,7 @@ static const char *get_ksymbol(struct module *mod,
3634{ 3657{
3635 unsigned int i, best = 0; 3658 unsigned int i, best = 0;
3636 unsigned long nextval; 3659 unsigned long nextval;
3660 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
3637 3661
3638 /* At worse, next value is at end of module */ 3662 /* At worse, next value is at end of module */
3639 if (within_module_init(addr, mod)) 3663 if (within_module_init(addr, mod))
@@ -3643,32 +3667,32 @@ static const char *get_ksymbol(struct module *mod,
3643 3667
3644 /* Scan for closest preceding symbol, and next symbol. (ELF 3668 /* Scan for closest preceding symbol, and next symbol. (ELF
3645 starts real symbols at 1). */ 3669 starts real symbols at 1). */
3646 for (i = 1; i < mod->num_symtab; i++) { 3670 for (i = 1; i < kallsyms->num_symtab; i++) {
3647 if (mod->symtab[i].st_shndx == SHN_UNDEF) 3671 if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
3648 continue; 3672 continue;
3649 3673
3650 /* We ignore unnamed symbols: they're uninformative 3674 /* We ignore unnamed symbols: they're uninformative
3651 * and inserted at a whim. */ 3675 * and inserted at a whim. */
3652 if (mod->symtab[i].st_value <= addr 3676 if (*symname(kallsyms, i) == '\0'
3653 && mod->symtab[i].st_value > mod->symtab[best].st_value 3677 || is_arm_mapping_symbol(symname(kallsyms, i)))
3654 && *(mod->strtab + mod->symtab[i].st_name) != '\0' 3678 continue;
3655 && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) 3679
3680 if (kallsyms->symtab[i].st_value <= addr
3681 && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
3656 best = i; 3682 best = i;
3657 if (mod->symtab[i].st_value > addr 3683 if (kallsyms->symtab[i].st_value > addr
3658 && mod->symtab[i].st_value < nextval 3684 && kallsyms->symtab[i].st_value < nextval)
3659 && *(mod->strtab + mod->symtab[i].st_name) != '\0' 3685 nextval = kallsyms->symtab[i].st_value;
3660 && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
3661 nextval = mod->symtab[i].st_value;
3662 } 3686 }
3663 3687
3664 if (!best) 3688 if (!best)
3665 return NULL; 3689 return NULL;
3666 3690
3667 if (size) 3691 if (size)
3668 *size = nextval - mod->symtab[best].st_value; 3692 *size = nextval - kallsyms->symtab[best].st_value;
3669 if (offset) 3693 if (offset)
3670 *offset = addr - mod->symtab[best].st_value; 3694 *offset = addr - kallsyms->symtab[best].st_value;
3671 return mod->strtab + mod->symtab[best].st_name; 3695 return symname(kallsyms, best);
3672} 3696}
3673 3697
3674/* For kallsyms to ask for address resolution. NULL means not found. Careful 3698/* For kallsyms to ask for address resolution. NULL means not found. Careful
@@ -3758,19 +3782,21 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
3758 3782
3759 preempt_disable(); 3783 preempt_disable();
3760 list_for_each_entry_rcu(mod, &modules, list) { 3784 list_for_each_entry_rcu(mod, &modules, list) {
3785 struct mod_kallsyms *kallsyms;
3786
3761 if (mod->state == MODULE_STATE_UNFORMED) 3787 if (mod->state == MODULE_STATE_UNFORMED)
3762 continue; 3788 continue;
3763 if (symnum < mod->num_symtab) { 3789 kallsyms = rcu_dereference_sched(mod->kallsyms);
3764 *value = mod->symtab[symnum].st_value; 3790 if (symnum < kallsyms->num_symtab) {
3765 *type = mod->symtab[symnum].st_info; 3791 *value = kallsyms->symtab[symnum].st_value;
3766 strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, 3792 *type = kallsyms->symtab[symnum].st_info;
3767 KSYM_NAME_LEN); 3793 strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
3768 strlcpy(module_name, mod->name, MODULE_NAME_LEN); 3794 strlcpy(module_name, mod->name, MODULE_NAME_LEN);
3769 *exported = is_exported(name, *value, mod); 3795 *exported = is_exported(name, *value, mod);
3770 preempt_enable(); 3796 preempt_enable();
3771 return 0; 3797 return 0;
3772 } 3798 }
3773 symnum -= mod->num_symtab; 3799 symnum -= kallsyms->num_symtab;
3774 } 3800 }
3775 preempt_enable(); 3801 preempt_enable();
3776 return -ERANGE; 3802 return -ERANGE;
@@ -3779,11 +3805,12 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
3779static unsigned long mod_find_symname(struct module *mod, const char *name) 3805static unsigned long mod_find_symname(struct module *mod, const char *name)
3780{ 3806{
3781 unsigned int i; 3807 unsigned int i;
3808 struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
3782 3809
3783 for (i = 0; i < mod->num_symtab; i++) 3810 for (i = 0; i < kallsyms->num_symtab; i++)
3784 if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 && 3811 if (strcmp(name, symname(kallsyms, i)) == 0 &&
3785 mod->symtab[i].st_info != 'U') 3812 kallsyms->symtab[i].st_info != 'U')
3786 return mod->symtab[i].st_value; 3813 return kallsyms->symtab[i].st_value;
3787 return 0; 3814 return 0;
3788} 3815}
3789 3816
@@ -3822,11 +3849,14 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
3822 module_assert_mutex(); 3849 module_assert_mutex();
3823 3850
3824 list_for_each_entry(mod, &modules, list) { 3851 list_for_each_entry(mod, &modules, list) {
3852 /* We hold module_mutex: no need for rcu_dereference_sched */
3853 struct mod_kallsyms *kallsyms = mod->kallsyms;
3854
3825 if (mod->state == MODULE_STATE_UNFORMED) 3855 if (mod->state == MODULE_STATE_UNFORMED)
3826 continue; 3856 continue;
3827 for (i = 0; i < mod->num_symtab; i++) { 3857 for (i = 0; i < kallsyms->num_symtab; i++) {
3828 ret = fn(data, mod->strtab + mod->symtab[i].st_name, 3858 ret = fn(data, symname(kallsyms, i),
3829 mod, mod->symtab[i].st_value); 3859 mod, kallsyms->symtab[i].st_value);
3830 if (ret != 0) 3860 if (ret != 0)
3831 return ret; 3861 return ret;
3832 } 3862 }