aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/kernel/module.c b/kernel/module.c
index ae79ce615cb9..88cec1ddb1e3 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -135,7 +135,7 @@ static int param_set_bool_enable_only(const char *val,
135} 135}
136 136
137static const struct kernel_param_ops param_ops_bool_enable_only = { 137static const struct kernel_param_ops param_ops_bool_enable_only = {
138 .flags = KERNEL_PARAM_FL_NOARG, 138 .flags = KERNEL_PARAM_OPS_FL_NOARG,
139 .set = param_set_bool_enable_only, 139 .set = param_set_bool_enable_only,
140 .get = param_get_bool, 140 .get = param_get_bool,
141}; 141};
@@ -1842,7 +1842,9 @@ static void free_module(struct module *mod)
1842 1842
1843 /* We leave it in list to prevent duplicate loads, but make sure 1843 /* We leave it in list to prevent duplicate loads, but make sure
1844 * that noone uses it while it's being deconstructed. */ 1844 * that noone uses it while it's being deconstructed. */
1845 mutex_lock(&module_mutex);
1845 mod->state = MODULE_STATE_UNFORMED; 1846 mod->state = MODULE_STATE_UNFORMED;
1847 mutex_unlock(&module_mutex);
1846 1848
1847 /* Remove dynamic debug info */ 1849 /* Remove dynamic debug info */
1848 ddebug_remove_module(mod->name); 1850 ddebug_remove_module(mod->name);
@@ -3304,6 +3306,11 @@ static int load_module(struct load_info *info, const char __user *uargs,
3304 mutex_lock(&module_mutex); 3306 mutex_lock(&module_mutex);
3305 module_bug_cleanup(mod); 3307 module_bug_cleanup(mod);
3306 mutex_unlock(&module_mutex); 3308 mutex_unlock(&module_mutex);
3309
3310 /* we can't deallocate the module until we clear memory protection */
3311 unset_module_init_ro_nx(mod);
3312 unset_module_core_ro_nx(mod);
3313
3307 ddebug_cleanup: 3314 ddebug_cleanup:
3308 dynamic_debug_remove(info->debug); 3315 dynamic_debug_remove(info->debug);
3309 synchronize_sched(); 3316 synchronize_sched();
@@ -3381,7 +3388,9 @@ static inline int within(unsigned long addr, void *start, unsigned long size)
3381 */ 3388 */
3382static inline int is_arm_mapping_symbol(const char *str) 3389static inline int is_arm_mapping_symbol(const char *str)
3383{ 3390{
3384 return str[0] == '$' && strchr("atd", str[1]) 3391 if (str[0] == '.' && str[1] == 'L')
3392 return true;
3393 return str[0] == '$' && strchr("axtd", str[1])
3385 && (str[2] == '\0' || str[2] == '.'); 3394 && (str[2] == '\0' || str[2] == '.');
3386} 3395}
3387 3396
@@ -3444,8 +3453,7 @@ const char *module_address_lookup(unsigned long addr,
3444 list_for_each_entry_rcu(mod, &modules, list) { 3453 list_for_each_entry_rcu(mod, &modules, list) {
3445 if (mod->state == MODULE_STATE_UNFORMED) 3454 if (mod->state == MODULE_STATE_UNFORMED)
3446 continue; 3455 continue;
3447 if (within_module_init(addr, mod) || 3456 if (within_module(addr, mod)) {
3448 within_module_core(addr, mod)) {
3449 if (modname) 3457 if (modname)
3450 *modname = mod->name; 3458 *modname = mod->name;
3451 ret = get_ksymbol(mod, addr, size, offset); 3459 ret = get_ksymbol(mod, addr, size, offset);
@@ -3469,8 +3477,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
3469 list_for_each_entry_rcu(mod, &modules, list) { 3477 list_for_each_entry_rcu(mod, &modules, list) {
3470 if (mod->state == MODULE_STATE_UNFORMED) 3478 if (mod->state == MODULE_STATE_UNFORMED)
3471 continue; 3479 continue;
3472 if (within_module_init(addr, mod) || 3480 if (within_module(addr, mod)) {
3473 within_module_core(addr, mod)) {
3474 const char *sym; 3481 const char *sym;
3475 3482
3476 sym = get_ksymbol(mod, addr, NULL, NULL); 3483 sym = get_ksymbol(mod, addr, NULL, NULL);
@@ -3495,8 +3502,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
3495 list_for_each_entry_rcu(mod, &modules, list) { 3502 list_for_each_entry_rcu(mod, &modules, list) {
3496 if (mod->state == MODULE_STATE_UNFORMED) 3503 if (mod->state == MODULE_STATE_UNFORMED)
3497 continue; 3504 continue;
3498 if (within_module_init(addr, mod) || 3505 if (within_module(addr, mod)) {
3499 within_module_core(addr, mod)) {
3500 const char *sym; 3506 const char *sym;
3501 3507
3502 sym = get_ksymbol(mod, addr, size, offset); 3508 sym = get_ksymbol(mod, addr, size, offset);
@@ -3760,8 +3766,7 @@ struct module *__module_address(unsigned long addr)
3760 list_for_each_entry_rcu(mod, &modules, list) { 3766 list_for_each_entry_rcu(mod, &modules, list) {
3761 if (mod->state == MODULE_STATE_UNFORMED) 3767 if (mod->state == MODULE_STATE_UNFORMED)
3762 continue; 3768 continue;
3763 if (within_module_core(addr, mod) 3769 if (within_module(addr, mod))
3764 || within_module_init(addr, mod))
3765 return mod; 3770 return mod;
3766 } 3771 }
3767 return NULL; 3772 return NULL;