diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/kernel/module.c b/kernel/module.c index 0b9aa8ab89f0..a9020bdd4cf6 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -98,6 +98,10 @@ DEFINE_MUTEX(module_mutex); | |||
98 | EXPORT_SYMBOL_GPL(module_mutex); | 98 | EXPORT_SYMBOL_GPL(module_mutex); |
99 | static LIST_HEAD(modules); | 99 | static LIST_HEAD(modules); |
100 | 100 | ||
101 | /* Work queue for freeing init sections in success case */ | ||
102 | static struct work_struct init_free_wq; | ||
103 | static struct llist_head init_free_list; | ||
104 | |||
101 | #ifdef CONFIG_MODULES_TREE_LOOKUP | 105 | #ifdef CONFIG_MODULES_TREE_LOOKUP |
102 | 106 | ||
103 | /* | 107 | /* |
@@ -1949,9 +1953,16 @@ void module_enable_ro(const struct module *mod, bool after_init) | |||
1949 | if (!rodata_enabled) | 1953 | if (!rodata_enabled) |
1950 | return; | 1954 | return; |
1951 | 1955 | ||
1956 | set_vm_flush_reset_perms(mod->core_layout.base); | ||
1957 | set_vm_flush_reset_perms(mod->init_layout.base); | ||
1952 | frob_text(&mod->core_layout, set_memory_ro); | 1958 | frob_text(&mod->core_layout, set_memory_ro); |
1959 | frob_text(&mod->core_layout, set_memory_x); | ||
1960 | |||
1953 | frob_rodata(&mod->core_layout, set_memory_ro); | 1961 | frob_rodata(&mod->core_layout, set_memory_ro); |
1962 | |||
1954 | frob_text(&mod->init_layout, set_memory_ro); | 1963 | frob_text(&mod->init_layout, set_memory_ro); |
1964 | frob_text(&mod->init_layout, set_memory_x); | ||
1965 | |||
1955 | frob_rodata(&mod->init_layout, set_memory_ro); | 1966 | frob_rodata(&mod->init_layout, set_memory_ro); |
1956 | 1967 | ||
1957 | if (after_init) | 1968 | if (after_init) |
@@ -1967,15 +1978,6 @@ static void module_enable_nx(const struct module *mod) | |||
1967 | frob_writable_data(&mod->init_layout, set_memory_nx); | 1978 | frob_writable_data(&mod->init_layout, set_memory_nx); |
1968 | } | 1979 | } |
1969 | 1980 | ||
1970 | static void module_disable_nx(const struct module *mod) | ||
1971 | { | ||
1972 | frob_rodata(&mod->core_layout, set_memory_x); | ||
1973 | frob_ro_after_init(&mod->core_layout, set_memory_x); | ||
1974 | frob_writable_data(&mod->core_layout, set_memory_x); | ||
1975 | frob_rodata(&mod->init_layout, set_memory_x); | ||
1976 | frob_writable_data(&mod->init_layout, set_memory_x); | ||
1977 | } | ||
1978 | |||
1979 | /* Iterate through all modules and set each module's text as RW */ | 1981 | /* Iterate through all modules and set each module's text as RW */ |
1980 | void set_all_modules_text_rw(void) | 1982 | void set_all_modules_text_rw(void) |
1981 | { | 1983 | { |
@@ -2019,23 +2021,8 @@ void set_all_modules_text_ro(void) | |||
2019 | } | 2021 | } |
2020 | mutex_unlock(&module_mutex); | 2022 | mutex_unlock(&module_mutex); |
2021 | } | 2023 | } |
2022 | |||
2023 | static void disable_ro_nx(const struct module_layout *layout) | ||
2024 | { | ||
2025 | if (rodata_enabled) { | ||
2026 | frob_text(layout, set_memory_rw); | ||
2027 | frob_rodata(layout, set_memory_rw); | ||
2028 | frob_ro_after_init(layout, set_memory_rw); | ||
2029 | } | ||
2030 | frob_rodata(layout, set_memory_x); | ||
2031 | frob_ro_after_init(layout, set_memory_x); | ||
2032 | frob_writable_data(layout, set_memory_x); | ||
2033 | } | ||
2034 | |||
2035 | #else | 2024 | #else |
2036 | static void disable_ro_nx(const struct module_layout *layout) { } | ||
2037 | static void module_enable_nx(const struct module *mod) { } | 2025 | static void module_enable_nx(const struct module *mod) { } |
2038 | static void module_disable_nx(const struct module *mod) { } | ||
2039 | #endif | 2026 | #endif |
2040 | 2027 | ||
2041 | #ifdef CONFIG_LIVEPATCH | 2028 | #ifdef CONFIG_LIVEPATCH |
@@ -2115,6 +2102,11 @@ static void free_module_elf(struct module *mod) | |||
2115 | 2102 | ||
2116 | void __weak module_memfree(void *module_region) | 2103 | void __weak module_memfree(void *module_region) |
2117 | { | 2104 | { |
2105 | /* | ||
2106 | * This memory may be RO, and freeing RO memory in an interrupt is not | ||
2107 | * supported by vmalloc. | ||
2108 | */ | ||
2109 | WARN_ON(in_interrupt()); | ||
2118 | vfree(module_region); | 2110 | vfree(module_region); |
2119 | } | 2111 | } |
2120 | 2112 | ||
@@ -2166,7 +2158,6 @@ static void free_module(struct module *mod) | |||
2166 | mutex_unlock(&module_mutex); | 2158 | mutex_unlock(&module_mutex); |
2167 | 2159 | ||
2168 | /* This may be empty, but that's OK */ | 2160 | /* This may be empty, but that's OK */ |
2169 | disable_ro_nx(&mod->init_layout); | ||
2170 | module_arch_freeing_init(mod); | 2161 | module_arch_freeing_init(mod); |
2171 | module_memfree(mod->init_layout.base); | 2162 | module_memfree(mod->init_layout.base); |
2172 | kfree(mod->args); | 2163 | kfree(mod->args); |
@@ -2176,7 +2167,6 @@ static void free_module(struct module *mod) | |||
2176 | lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); | 2167 | lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); |
2177 | 2168 | ||
2178 | /* Finally, free the core (containing the module structure) */ | 2169 | /* Finally, free the core (containing the module structure) */ |
2179 | disable_ro_nx(&mod->core_layout); | ||
2180 | module_memfree(mod->core_layout.base); | 2170 | module_memfree(mod->core_layout.base); |
2181 | } | 2171 | } |
2182 | 2172 | ||
@@ -3415,17 +3405,34 @@ static void do_mod_ctors(struct module *mod) | |||
3415 | 3405 | ||
3416 | /* For freeing module_init on success, in case kallsyms traversing */ | 3406 | /* For freeing module_init on success, in case kallsyms traversing */ |
3417 | struct mod_initfree { | 3407 | struct mod_initfree { |
3418 | struct rcu_head rcu; | 3408 | struct llist_node node; |
3419 | void *module_init; | 3409 | void *module_init; |
3420 | }; | 3410 | }; |
3421 | 3411 | ||
3422 | static void do_free_init(struct rcu_head *head) | 3412 | static void do_free_init(struct work_struct *w) |
3423 | { | 3413 | { |
3424 | struct mod_initfree *m = container_of(head, struct mod_initfree, rcu); | 3414 | struct llist_node *pos, *n, *list; |
3425 | module_memfree(m->module_init); | 3415 | struct mod_initfree *initfree; |
3426 | kfree(m); | 3416 | |
3417 | list = llist_del_all(&init_free_list); | ||
3418 | |||
3419 | synchronize_rcu(); | ||
3420 | |||
3421 | llist_for_each_safe(pos, n, list) { | ||
3422 | initfree = container_of(pos, struct mod_initfree, node); | ||
3423 | module_memfree(initfree->module_init); | ||
3424 | kfree(initfree); | ||
3425 | } | ||
3427 | } | 3426 | } |
3428 | 3427 | ||
3428 | static int __init modules_wq_init(void) | ||
3429 | { | ||
3430 | INIT_WORK(&init_free_wq, do_free_init); | ||
3431 | init_llist_head(&init_free_list); | ||
3432 | return 0; | ||
3433 | } | ||
3434 | module_init(modules_wq_init); | ||
3435 | |||
3429 | /* | 3436 | /* |
3430 | * This is where the real work happens. | 3437 | * This is where the real work happens. |
3431 | * | 3438 | * |
@@ -3502,7 +3509,6 @@ static noinline int do_init_module(struct module *mod) | |||
3502 | #endif | 3509 | #endif |
3503 | module_enable_ro(mod, true); | 3510 | module_enable_ro(mod, true); |
3504 | mod_tree_remove_init(mod); | 3511 | mod_tree_remove_init(mod); |
3505 | disable_ro_nx(&mod->init_layout); | ||
3506 | module_arch_freeing_init(mod); | 3512 | module_arch_freeing_init(mod); |
3507 | mod->init_layout.base = NULL; | 3513 | mod->init_layout.base = NULL; |
3508 | mod->init_layout.size = 0; | 3514 | mod->init_layout.size = 0; |
@@ -3513,14 +3519,18 @@ static noinline int do_init_module(struct module *mod) | |||
3513 | * We want to free module_init, but be aware that kallsyms may be | 3519 | * We want to free module_init, but be aware that kallsyms may be |
3514 | * walking this with preempt disabled. In all the failure paths, we | 3520 | * walking this with preempt disabled. In all the failure paths, we |
3515 | * call synchronize_rcu(), but we don't want to slow down the success | 3521 | * call synchronize_rcu(), but we don't want to slow down the success |
3516 | * path, so use actual RCU here. | 3522 | * path. module_memfree() cannot be called in an interrupt, so do the |
3523 | * work and call synchronize_rcu() in a work queue. | ||
3524 | * | ||
3517 | * Note that module_alloc() on most architectures creates W+X page | 3525 | * Note that module_alloc() on most architectures creates W+X page |
3518 | * mappings which won't be cleaned up until do_free_init() runs. Any | 3526 | * mappings which won't be cleaned up until do_free_init() runs. Any |
3519 | * code such as mark_rodata_ro() which depends on those mappings to | 3527 | * code such as mark_rodata_ro() which depends on those mappings to |
3520 | * be cleaned up needs to sync with the queued work - ie | 3528 | * be cleaned up needs to sync with the queued work - ie |
3521 | * rcu_barrier() | 3529 | * rcu_barrier() |
3522 | */ | 3530 | */ |
3523 | call_rcu(&freeinit->rcu, do_free_init); | 3531 | if (llist_add(&freeinit->node, &init_free_list)) |
3532 | schedule_work(&init_free_wq); | ||
3533 | |||
3524 | mutex_unlock(&module_mutex); | 3534 | mutex_unlock(&module_mutex); |
3525 | wake_up_all(&module_wq); | 3535 | wake_up_all(&module_wq); |
3526 | 3536 | ||
@@ -3817,10 +3827,6 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3817 | module_bug_cleanup(mod); | 3827 | module_bug_cleanup(mod); |
3818 | mutex_unlock(&module_mutex); | 3828 | mutex_unlock(&module_mutex); |
3819 | 3829 | ||
3820 | /* we can't deallocate the module until we clear memory protection */ | ||
3821 | module_disable_ro(mod); | ||
3822 | module_disable_nx(mod); | ||
3823 | |||
3824 | ddebug_cleanup: | 3830 | ddebug_cleanup: |
3825 | ftrace_release_mod(mod); | 3831 | ftrace_release_mod(mod); |
3826 | dynamic_debug_remove(mod, info->debug); | 3832 | dynamic_debug_remove(mod, info->debug); |