diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2020-10-15 20:37:01 +0200 | 
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2020-10-15 20:37:01 +0200 | 
| commit | 62b31a045757eac81fed94b19df47418a0818528 (patch) | |
| tree | 285fda56df8304dff6ba929bad65ddfb4e4fd726 /kernel/module.c | |
| parent | cc51d171776f3a6acb6828bad0b780a4cacf5423 (diff) | |
| parent | c27e08820bc6cb7d483a8d87589bdbbbf10f2306 (diff) | |
Merge branch 'for-5.10/core' into for-linus
- nonblocking read semantics fix for hid-debug
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 60 | 
1 files changed, 43 insertions, 17 deletions
diff --git a/kernel/module.c b/kernel/module.c index 8fa2600bde6a..1c5cff34d9f2 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -422,7 +422,7 @@ static bool each_symbol_in_section(const struct symsearch *arr,  }  /* Returns true as soon as fn returns true, otherwise false. */ -bool each_symbol_section(bool (*fn)(const struct symsearch *arr, +static bool each_symbol_section(bool (*fn)(const struct symsearch *arr,  				    struct module *owner,  				    void *data),  			 void *data) @@ -484,7 +484,6 @@ bool each_symbol_section(bool (*fn)(const struct symsearch *arr,  	}  	return false;  } -EXPORT_SYMBOL_GPL(each_symbol_section);  struct find_symbol_arg {  	/* Input */ @@ -496,6 +495,7 @@ struct find_symbol_arg {  	struct module *owner;  	const s32 *crc;  	const struct kernel_symbol *sym; +	enum mod_license license;  };  static bool check_exported_symbol(const struct symsearch *syms, @@ -505,9 +505,9 @@ static bool check_exported_symbol(const struct symsearch *syms,  	struct find_symbol_arg *fsa = data;  	if (!fsa->gplok) { -		if (syms->licence == GPL_ONLY) +		if (syms->license == GPL_ONLY)  			return false; -		if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) { +		if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) {  			pr_warn("Symbol %s is being used by a non-GPL module, "  				"which will not be allowed in the future\n",  				fsa->name); @@ -529,6 +529,7 @@ static bool check_exported_symbol(const struct symsearch *syms,  	fsa->owner = owner;  	fsa->crc = symversion(syms->crcs, symnum);  	fsa->sym = &syms->start[symnum]; +	fsa->license = syms->license;  	return true;  } @@ -585,9 +586,10 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,  /* Find an exported symbol and return it, along with, (optional) crc and   * (optional) module which owns it.  Needs preempt disabled or module_mutex. */ -const struct kernel_symbol *find_symbol(const char *name, +static const struct kernel_symbol *find_symbol(const char *name,  					struct module **owner,  					const s32 **crc, +					enum mod_license *license,  					bool gplok,  					bool warn)  { @@ -602,13 +604,14 @@ const struct kernel_symbol *find_symbol(const char *name,  			*owner = fsa.owner;  		if (crc)  			*crc = fsa.crc; +		if (license) +			*license = fsa.license;  		return fsa.sym;  	}  	pr_debug("Failed to find symbol %s\n", name);  	return NULL;  } -EXPORT_SYMBOL_GPL(find_symbol);  /*   * Search for module by name: must hold module_mutex (or preempt disabled @@ -869,7 +872,7 @@ static int add_module_usage(struct module *a, struct module *b)  }  /* Module a uses b: caller needs module_mutex() */ -int ref_module(struct module *a, struct module *b) +static int ref_module(struct module *a, struct module *b)  {  	int err; @@ -888,7 +891,6 @@ int ref_module(struct module *a, struct module *b)  	}  	return 0;  } -EXPORT_SYMBOL_GPL(ref_module);  /* Clear the unload stuff of the module. */  static void module_unload_free(struct module *mod) @@ -1077,7 +1079,7 @@ void __symbol_put(const char *symbol)  	struct module *owner;  	preempt_disable(); -	if (!find_symbol(symbol, &owner, NULL, true, false)) +	if (!find_symbol(symbol, &owner, NULL, NULL, true, false))  		BUG();  	module_put(owner);  	preempt_enable(); @@ -1169,11 +1171,10 @@ static inline void module_unload_free(struct module *mod)  {  } -int ref_module(struct module *a, struct module *b) +static int ref_module(struct module *a, struct module *b)  {  	return strong_try_module_get(b);  } -EXPORT_SYMBOL_GPL(ref_module);  static inline int module_unload_init(struct module *mod)  { @@ -1356,7 +1357,7 @@ static inline int check_modstruct_version(const struct load_info *info,  	 * locking is necessary -- use preempt_disable() to placate lockdep.  	 */  	preempt_disable(); -	if (!find_symbol("module_layout", NULL, &crc, true, false)) { +	if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) {  		preempt_enable();  		BUG();  	} @@ -1430,6 +1431,24 @@ static int verify_namespace_is_imported(const struct load_info *info,  	return 0;  } +static bool inherit_taint(struct module *mod, struct module *owner) +{ +	if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints)) +		return true; + +	if (mod->using_gplonly_symbols) { +		pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n", +			mod->name, owner->name); +		return false; +	} + +	if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) { +		pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n", +			mod->name, owner->name); +		set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints); +	} +	return true; +}  /* Resolve a symbol for this module.  I.e. if we find one, record usage. */  static const struct kernel_symbol *resolve_symbol(struct module *mod, @@ -1440,6 +1459,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,  	struct module *owner;  	const struct kernel_symbol *sym;  	const s32 *crc; +	enum mod_license license;  	int err;  	/* @@ -1449,11 +1469,19 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,  	 */  	sched_annotate_sleep();  	mutex_lock(&module_mutex); -	sym = find_symbol(name, &owner, &crc, +	sym = find_symbol(name, &owner, &crc, &license,  			  !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);  	if (!sym)  		goto unlock; +	if (license == GPL_ONLY) +		mod->using_gplonly_symbols = true; + +	if (!inherit_taint(mod, owner)) { +		sym = NULL; +		goto getname; +	} +  	if (!check_version(info, name, mod, crc)) {  		sym = ERR_PTR(-EINVAL);  		goto getname; @@ -2236,7 +2264,7 @@ void *__symbol_get(const char *symbol)  	const struct kernel_symbol *sym;  	preempt_disable(); -	sym = find_symbol(symbol, &owner, NULL, true, true); +	sym = find_symbol(symbol, &owner, NULL, NULL, true, true);  	if (sym && strong_try_module_get(owner))  		sym = NULL;  	preempt_enable(); @@ -2272,7 +2300,7 @@ static int verify_exported_symbols(struct module *mod)  	for (i = 0; i < ARRAY_SIZE(arr); i++) {  		for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {  			if (find_symbol(kernel_symbol_name(s), &owner, NULL, -					true, false)) { +					NULL, true, false)) {  				pr_err("%s: exports duplicate symbol %s"  				       " (owned by %s)\n",  				       mod->name, kernel_symbol_name(s), @@ -4489,7 +4517,6 @@ struct module *__module_address(unsigned long addr)  	}  	return mod;  } -EXPORT_SYMBOL_GPL(__module_address);  /*   * is_module_text_address - is this address inside module code? @@ -4528,7 +4555,6 @@ struct module *__module_text_address(unsigned long addr)  	}  	return mod;  } -EXPORT_SYMBOL_GPL(__module_text_address);  /* Don't grab lock, we're oopsing. */  void print_modules(void)  | 
