diff options
Diffstat (limited to 'scripts/mod/modpost.c')
| -rw-r--r-- | scripts/mod/modpost.c | 56 | 
1 files changed, 51 insertions, 5 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index be89921d60b6..5ca7c268294e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -28,6 +28,8 @@  #include "modpost.h"  #include "../../include/linux/license.h" +#define MODULE_NS_PREFIX "module:" +  static bool module_enabled;  /* Are we using CONFIG_MODVERSIONS? */  static bool modversions; @@ -1595,11 +1597,14 @@ static void read_symbols(const char *modname)  			license = get_next_modinfo(&info, "license", license);  		} -		namespace = get_modinfo(&info, "import_ns"); -		while (namespace) { +		for (namespace = get_modinfo(&info, "import_ns"); +		     namespace; +		     namespace = get_next_modinfo(&info, "import_ns", namespace)) { +			if (strstarts(namespace, MODULE_NS_PREFIX)) +				error("%s: explicitly importing namespace \"%s\" is not allowed.\n", +				      mod->name, namespace); +  			add_namespace(&mod->imported_namespaces, namespace); -			namespace = get_next_modinfo(&info, "import_ns", -						     namespace);  		}  		if (!get_modinfo(&info, "description")) @@ -1684,6 +1689,46 @@ void buf_write(struct buffer *buf, const char *s, int len)  	buf->pos += len;  } +/** + * verify_module_namespace() - does @modname have access to this symbol's @namespace + * @namespace: export symbol namespace + * @modname: module name + * + * If @namespace is prefixed with "module:" to indicate it is a module namespace + * then test if @modname matches any of the comma separated patterns. + * + * The patterns only support tail-glob. + */ +static bool verify_module_namespace(const char *namespace, const char *modname) +{ +	size_t len, modlen = strlen(modname); +	const char *prefix = "module:"; +	const char *sep; +	bool glob; + +	if (!strstarts(namespace, prefix)) +		return false; + +	for (namespace += strlen(prefix); *namespace; namespace = sep) { +		sep = strchrnul(namespace, ','); +		len = sep - namespace; + +		glob = false; +		if (sep[-1] == '*') { +			len--; +			glob = true; +		} + +		if (*sep) +			sep++; + +		if (strncmp(namespace, modname, len) == 0 && (glob || len == modlen)) +			return true; +	} + +	return false; +} +  static void check_exports(struct module *mod)  {  	struct symbol *s, *exp; @@ -1711,7 +1756,8 @@ static void check_exports(struct module *mod)  		basename = get_basename(mod->name); -		if (!contains_namespace(&mod->imported_namespaces, exp->namespace)) { +		if (!verify_module_namespace(exp->namespace, basename) && +		    !contains_namespace(&mod->imported_namespaces, exp->namespace)) {  			modpost_log(!allow_missing_ns_imports,  				    "module %s uses symbol %s from namespace %s, but does not import it.\n",  				    basename, exp->name, exp->namespace);  | 
