diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-22 13:40:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-22 13:40:36 -0500 |
commit | 193934123c84fa168d0326aa6ab8d58cd173b32a (patch) | |
tree | 1e2d93840c4e0c49e327d4493913e6c9db861c87 /kernel | |
parent | b942c653ae265abbd31032f3b4f5f857e5c7c723 (diff) | |
parent | d5db139ab3764640e0882a1746e7b9fdee33fd87 (diff) |
Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module and param fixes from Rusty Russell:
"Surprising number of fixes this merge window :(
The first two are minor fallout from the param rework which went in
this merge window.
The next three are a series which fixes a longstanding (but never
previously reported and unlikely , so no CC stable) race between
kallsyms and freeing the init section.
Finally, a minor cleanup as our module refcount will now be -1 during
unload"
* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
module: make module_refcount() a signed integer.
module: fix race in kallsyms resolution during module load success.
module: remove mod arg from module_free, rename module_memfree().
module_arch_freeing_init(): new hook for archs before module->module_init freed.
param: fix uninitialized read with CONFIG_DEBUG_LOCK_ALLOC
param: initialize store function to NULL if not available.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bpf/core.c | 2 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 2 | ||||
-rw-r--r-- | kernel/kprobes.c | 2 | ||||
-rw-r--r-- | kernel/module.c | 91 | ||||
-rw-r--r-- | kernel/params.c | 3 |
5 files changed, 74 insertions, 26 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index d6594e457a25..a64e7a207d2b 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
@@ -163,7 +163,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, | |||
163 | 163 | ||
164 | void bpf_jit_binary_free(struct bpf_binary_header *hdr) | 164 | void bpf_jit_binary_free(struct bpf_binary_header *hdr) |
165 | { | 165 | { |
166 | module_free(NULL, hdr); | 166 | module_memfree(hdr); |
167 | } | 167 | } |
168 | #endif /* CONFIG_BPF_JIT */ | 168 | #endif /* CONFIG_BPF_JIT */ |
169 | 169 | ||
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index f191bddf64b8..7b40c5f07dce 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -2023,7 +2023,7 @@ static int kdb_lsmod(int argc, const char **argv) | |||
2023 | kdb_printf("%-20s%8u 0x%p ", mod->name, | 2023 | kdb_printf("%-20s%8u 0x%p ", mod->name, |
2024 | mod->core_size, (void *)mod); | 2024 | mod->core_size, (void *)mod); |
2025 | #ifdef CONFIG_MODULE_UNLOAD | 2025 | #ifdef CONFIG_MODULE_UNLOAD |
2026 | kdb_printf("%4ld ", module_refcount(mod)); | 2026 | kdb_printf("%4d ", module_refcount(mod)); |
2027 | #endif | 2027 | #endif |
2028 | if (mod->state == MODULE_STATE_GOING) | 2028 | if (mod->state == MODULE_STATE_GOING) |
2029 | kdb_printf(" (Unloading)"); | 2029 | kdb_printf(" (Unloading)"); |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 06f58309fed2..ee619929cf90 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -127,7 +127,7 @@ static void *alloc_insn_page(void) | |||
127 | 127 | ||
128 | static void free_insn_page(void *page) | 128 | static void free_insn_page(void *page) |
129 | { | 129 | { |
130 | module_free(NULL, page); | 130 | module_memfree(page); |
131 | } | 131 | } |
132 | 132 | ||
133 | struct kprobe_insn_cache kprobe_insn_slots = { | 133 | struct kprobe_insn_cache kprobe_insn_slots = { |
diff --git a/kernel/module.c b/kernel/module.c index 3965511ae133..d856e96a3cce 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -772,9 +772,18 @@ static int try_stop_module(struct module *mod, int flags, int *forced) | |||
772 | return 0; | 772 | return 0; |
773 | } | 773 | } |
774 | 774 | ||
775 | unsigned long module_refcount(struct module *mod) | 775 | /** |
776 | * module_refcount - return the refcount or -1 if unloading | ||
777 | * | ||
778 | * @mod: the module we're checking | ||
779 | * | ||
780 | * Returns: | ||
781 | * -1 if the module is in the process of unloading | ||
782 | * otherwise the number of references in the kernel to the module | ||
783 | */ | ||
784 | int module_refcount(struct module *mod) | ||
776 | { | 785 | { |
777 | return (unsigned long)atomic_read(&mod->refcnt) - MODULE_REF_BASE; | 786 | return atomic_read(&mod->refcnt) - MODULE_REF_BASE; |
778 | } | 787 | } |
779 | EXPORT_SYMBOL(module_refcount); | 788 | EXPORT_SYMBOL(module_refcount); |
780 | 789 | ||
@@ -856,7 +865,7 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod) | |||
856 | struct module_use *use; | 865 | struct module_use *use; |
857 | int printed_something = 0; | 866 | int printed_something = 0; |
858 | 867 | ||
859 | seq_printf(m, " %lu ", module_refcount(mod)); | 868 | seq_printf(m, " %i ", module_refcount(mod)); |
860 | 869 | ||
861 | /* | 870 | /* |
862 | * Always include a trailing , so userspace can differentiate | 871 | * Always include a trailing , so userspace can differentiate |
@@ -908,7 +917,7 @@ EXPORT_SYMBOL_GPL(symbol_put_addr); | |||
908 | static ssize_t show_refcnt(struct module_attribute *mattr, | 917 | static ssize_t show_refcnt(struct module_attribute *mattr, |
909 | struct module_kobject *mk, char *buffer) | 918 | struct module_kobject *mk, char *buffer) |
910 | { | 919 | { |
911 | return sprintf(buffer, "%lu\n", module_refcount(mk->mod)); | 920 | return sprintf(buffer, "%i\n", module_refcount(mk->mod)); |
912 | } | 921 | } |
913 | 922 | ||
914 | static struct module_attribute modinfo_refcnt = | 923 | static struct module_attribute modinfo_refcnt = |
@@ -1795,7 +1804,7 @@ static void unset_module_core_ro_nx(struct module *mod) { } | |||
1795 | static void unset_module_init_ro_nx(struct module *mod) { } | 1804 | static void unset_module_init_ro_nx(struct module *mod) { } |
1796 | #endif | 1805 | #endif |
1797 | 1806 | ||
1798 | void __weak module_free(struct module *mod, void *module_region) | 1807 | void __weak module_memfree(void *module_region) |
1799 | { | 1808 | { |
1800 | vfree(module_region); | 1809 | vfree(module_region); |
1801 | } | 1810 | } |
@@ -1804,6 +1813,10 @@ void __weak module_arch_cleanup(struct module *mod) | |||
1804 | { | 1813 | { |
1805 | } | 1814 | } |
1806 | 1815 | ||
1816 | void __weak module_arch_freeing_init(struct module *mod) | ||
1817 | { | ||
1818 | } | ||
1819 | |||
1807 | /* Free a module, remove from lists, etc. */ | 1820 | /* Free a module, remove from lists, etc. */ |
1808 | static void free_module(struct module *mod) | 1821 | static void free_module(struct module *mod) |
1809 | { | 1822 | { |
@@ -1841,7 +1854,8 @@ static void free_module(struct module *mod) | |||
1841 | 1854 | ||
1842 | /* This may be NULL, but that's OK */ | 1855 | /* This may be NULL, but that's OK */ |
1843 | unset_module_init_ro_nx(mod); | 1856 | unset_module_init_ro_nx(mod); |
1844 | module_free(mod, mod->module_init); | 1857 | module_arch_freeing_init(mod); |
1858 | module_memfree(mod->module_init); | ||
1845 | kfree(mod->args); | 1859 | kfree(mod->args); |
1846 | percpu_modfree(mod); | 1860 | percpu_modfree(mod); |
1847 | 1861 | ||
@@ -1850,7 +1864,7 @@ static void free_module(struct module *mod) | |||
1850 | 1864 | ||
1851 | /* Finally, free the core (containing the module structure) */ | 1865 | /* Finally, free the core (containing the module structure) */ |
1852 | unset_module_core_ro_nx(mod); | 1866 | unset_module_core_ro_nx(mod); |
1853 | module_free(mod, mod->module_core); | 1867 | module_memfree(mod->module_core); |
1854 | 1868 | ||
1855 | #ifdef CONFIG_MPU | 1869 | #ifdef CONFIG_MPU |
1856 | update_protections(current->mm); | 1870 | update_protections(current->mm); |
@@ -2785,7 +2799,7 @@ static int move_module(struct module *mod, struct load_info *info) | |||
2785 | */ | 2799 | */ |
2786 | kmemleak_ignore(ptr); | 2800 | kmemleak_ignore(ptr); |
2787 | if (!ptr) { | 2801 | if (!ptr) { |
2788 | module_free(mod, mod->module_core); | 2802 | module_memfree(mod->module_core); |
2789 | return -ENOMEM; | 2803 | return -ENOMEM; |
2790 | } | 2804 | } |
2791 | memset(ptr, 0, mod->init_size); | 2805 | memset(ptr, 0, mod->init_size); |
@@ -2930,8 +2944,9 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) | |||
2930 | static void module_deallocate(struct module *mod, struct load_info *info) | 2944 | static void module_deallocate(struct module *mod, struct load_info *info) |
2931 | { | 2945 | { |
2932 | percpu_modfree(mod); | 2946 | percpu_modfree(mod); |
2933 | module_free(mod, mod->module_init); | 2947 | module_arch_freeing_init(mod); |
2934 | module_free(mod, mod->module_core); | 2948 | module_memfree(mod->module_init); |
2949 | module_memfree(mod->module_core); | ||
2935 | } | 2950 | } |
2936 | 2951 | ||
2937 | int __weak module_finalize(const Elf_Ehdr *hdr, | 2952 | int __weak module_finalize(const Elf_Ehdr *hdr, |
@@ -2983,10 +2998,31 @@ static void do_mod_ctors(struct module *mod) | |||
2983 | #endif | 2998 | #endif |
2984 | } | 2999 | } |
2985 | 3000 | ||
3001 | /* For freeing module_init on success, in case kallsyms traversing */ | ||
3002 | struct mod_initfree { | ||
3003 | struct rcu_head rcu; | ||
3004 | void *module_init; | ||
3005 | }; | ||
3006 | |||
3007 | static void do_free_init(struct rcu_head *head) | ||
3008 | { | ||
3009 | struct mod_initfree *m = container_of(head, struct mod_initfree, rcu); | ||
3010 | module_memfree(m->module_init); | ||
3011 | kfree(m); | ||
3012 | } | ||
3013 | |||
2986 | /* This is where the real work happens */ | 3014 | /* This is where the real work happens */ |
2987 | static int do_init_module(struct module *mod) | 3015 | static int do_init_module(struct module *mod) |
2988 | { | 3016 | { |
2989 | int ret = 0; | 3017 | int ret = 0; |
3018 | struct mod_initfree *freeinit; | ||
3019 | |||
3020 | freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL); | ||
3021 | if (!freeinit) { | ||
3022 | ret = -ENOMEM; | ||
3023 | goto fail; | ||
3024 | } | ||
3025 | freeinit->module_init = mod->module_init; | ||
2990 | 3026 | ||
2991 | /* | 3027 | /* |
2992 | * We want to find out whether @mod uses async during init. Clear | 3028 | * We want to find out whether @mod uses async during init. Clear |
@@ -2999,18 +3035,7 @@ static int do_init_module(struct module *mod) | |||
2999 | if (mod->init != NULL) | 3035 | if (mod->init != NULL) |
3000 | ret = do_one_initcall(mod->init); | 3036 | ret = do_one_initcall(mod->init); |
3001 | if (ret < 0) { | 3037 | if (ret < 0) { |
3002 | /* | 3038 | goto fail_free_freeinit; |
3003 | * Init routine failed: abort. Try to protect us from | ||
3004 | * buggy refcounters. | ||
3005 | */ | ||
3006 | mod->state = MODULE_STATE_GOING; | ||
3007 | synchronize_sched(); | ||
3008 | module_put(mod); | ||
3009 | blocking_notifier_call_chain(&module_notify_list, | ||
3010 | MODULE_STATE_GOING, mod); | ||
3011 | free_module(mod); | ||
3012 | wake_up_all(&module_wq); | ||
3013 | return ret; | ||
3014 | } | 3039 | } |
3015 | if (ret > 0) { | 3040 | if (ret > 0) { |
3016 | pr_warn("%s: '%s'->init suspiciously returned %d, it should " | 3041 | pr_warn("%s: '%s'->init suspiciously returned %d, it should " |
@@ -3055,15 +3080,35 @@ static int do_init_module(struct module *mod) | |||
3055 | mod->strtab = mod->core_strtab; | 3080 | mod->strtab = mod->core_strtab; |
3056 | #endif | 3081 | #endif |
3057 | unset_module_init_ro_nx(mod); | 3082 | unset_module_init_ro_nx(mod); |
3058 | module_free(mod, mod->module_init); | 3083 | module_arch_freeing_init(mod); |
3059 | mod->module_init = NULL; | 3084 | mod->module_init = NULL; |
3060 | mod->init_size = 0; | 3085 | mod->init_size = 0; |
3061 | mod->init_ro_size = 0; | 3086 | mod->init_ro_size = 0; |
3062 | mod->init_text_size = 0; | 3087 | mod->init_text_size = 0; |
3088 | /* | ||
3089 | * We want to free module_init, but be aware that kallsyms may be | ||
3090 | * walking this with preempt disabled. In all the failure paths, | ||
3091 | * we call synchronize_rcu/synchronize_sched, but we don't want | ||
3092 | * to slow down the success path, so use actual RCU here. | ||
3093 | */ | ||
3094 | call_rcu(&freeinit->rcu, do_free_init); | ||
3063 | mutex_unlock(&module_mutex); | 3095 | mutex_unlock(&module_mutex); |
3064 | wake_up_all(&module_wq); | 3096 | wake_up_all(&module_wq); |
3065 | 3097 | ||
3066 | return 0; | 3098 | return 0; |
3099 | |||
3100 | fail_free_freeinit: | ||
3101 | kfree(freeinit); | ||
3102 | fail: | ||
3103 | /* Try to protect us from buggy refcounters. */ | ||
3104 | mod->state = MODULE_STATE_GOING; | ||
3105 | synchronize_sched(); | ||
3106 | module_put(mod); | ||
3107 | blocking_notifier_call_chain(&module_notify_list, | ||
3108 | MODULE_STATE_GOING, mod); | ||
3109 | free_module(mod); | ||
3110 | wake_up_all(&module_wq); | ||
3111 | return ret; | ||
3067 | } | 3112 | } |
3068 | 3113 | ||
3069 | static int may_init_module(void) | 3114 | static int may_init_module(void) |
diff --git a/kernel/params.c b/kernel/params.c index 0af9b2c4e56c..728e05b167de 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -642,12 +642,15 @@ static __modinit int add_sysfs_param(struct module_kobject *mk, | |||
642 | mk->mp->grp.attrs = new_attrs; | 642 | mk->mp->grp.attrs = new_attrs; |
643 | 643 | ||
644 | /* Tack new one on the end. */ | 644 | /* Tack new one on the end. */ |
645 | memset(&mk->mp->attrs[mk->mp->num], 0, sizeof(mk->mp->attrs[0])); | ||
645 | sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr); | 646 | sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr); |
646 | mk->mp->attrs[mk->mp->num].param = kp; | 647 | mk->mp->attrs[mk->mp->num].param = kp; |
647 | mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show; | 648 | mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show; |
648 | /* Do not allow runtime DAC changes to make param writable. */ | 649 | /* Do not allow runtime DAC changes to make param writable. */ |
649 | if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0) | 650 | if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0) |
650 | mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store; | 651 | mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store; |
652 | else | ||
653 | mk->mp->attrs[mk->mp->num].mattr.store = NULL; | ||
651 | mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name; | 654 | mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name; |
652 | mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm; | 655 | mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm; |
653 | mk->mp->num++; | 656 | mk->mp->num++; |