diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 49 | 
1 files changed, 20 insertions, 29 deletions
| diff --git a/kernel/module.c b/kernel/module.c index d856e96a3cce..8426ad48362c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -56,6 +56,7 @@  #include <linux/async.h>  #include <linux/percpu.h>  #include <linux/kmemleak.h> +#include <linux/kasan.h>  #include <linux/jump_label.h>  #include <linux/pfn.h>  #include <linux/bsearch.h> @@ -1225,6 +1226,12 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,  	const unsigned long *crc;  	int err; +	/* +	 * The module_mutex should not be a heavily contended lock; +	 * if we get the occasional sleep here, we'll go an extra iteration +	 * in the wait_event_interruptible(), which is harmless. +	 */ +	sched_annotate_sleep();  	mutex_lock(&module_mutex);  	sym = find_symbol(name, &owner, &crc,  			  !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); @@ -1807,6 +1814,7 @@ static void unset_module_init_ro_nx(struct module *mod) { }  void __weak module_memfree(void *module_region)  {  	vfree(module_region); +	kasan_module_free(module_region);  }  void __weak module_arch_cleanup(struct module *mod) @@ -2978,6 +2986,12 @@ static bool finished_loading(const char *name)  	struct module *mod;  	bool ret; +	/* +	 * The module_mutex should not be a heavily contended lock; +	 * if we get the occasional sleep here, we'll go an extra iteration +	 * in the wait_event_interruptible(), which is harmless. +	 */ +	sched_annotate_sleep();  	mutex_lock(&module_mutex);  	mod = find_module_all(name, strlen(name), true);  	ret = !mod || mod->state == MODULE_STATE_LIVE @@ -3120,32 +3134,6 @@ static int may_init_module(void)  }  /* - * Can't use wait_event_interruptible() because our condition - * 'finished_loading()' contains a blocking primitive itself (mutex_lock). - */ -static int wait_finished_loading(struct module *mod) -{ -	DEFINE_WAIT_FUNC(wait, woken_wake_function); -	int ret = 0; - -	add_wait_queue(&module_wq, &wait); -	for (;;) { -		if (finished_loading(mod->name)) -			break; - -		if (signal_pending(current)) { -			ret = -ERESTARTSYS; -			break; -		} - -		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); -	} -	remove_wait_queue(&module_wq, &wait); - -	return ret; -} - -/*   * We try to place it in the list now to make sure it's unique before   * we dedicate too many resources.  In particular, temporary percpu   * memory exhaustion. @@ -3165,8 +3153,8 @@ again:  		    || old->state == MODULE_STATE_UNFORMED) {  			/* Wait in case it fails to load. */  			mutex_unlock(&module_mutex); - -			err = wait_finished_loading(mod); +			err = wait_event_interruptible(module_wq, +					       finished_loading(mod->name));  			if (err)  				goto out_unlocked;  			goto again; @@ -3265,7 +3253,7 @@ static int load_module(struct load_info *info, const char __user *uargs,  	mod->sig_ok = info->sig_ok;  	if (!mod->sig_ok) {  		pr_notice_once("%s: module verification failed: signature " -			       "and/or  required key missing - tainting " +			       "and/or required key missing - tainting "  			       "kernel\n", mod->name);  		add_taint_module(mod, TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK);  	} @@ -3356,6 +3344,9 @@ static int load_module(struct load_info *info, const char __user *uargs,  	module_bug_cleanup(mod);  	mutex_unlock(&module_mutex); +	/* Free lock-classes: */ +	lockdep_free_key_range(mod->module_core, mod->core_size); +  	/* we can't deallocate the module until we clear memory protection */  	unset_module_init_ro_nx(mod);  	unset_module_core_ro_nx(mod); |