Commit 520b1a14 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Masahiro Yamada
Browse files

module: Add module specific symbol namespace support



Designate the "module:${modname}" symbol namespace to mean: 'only
export to the named module'.

Notably, explicit imports of anything in the "module:" space is
forbidden.

Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
Reviewed-by: default avatarPetr Pavlu <petr.pavlu@suse.com>
Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
parent 6b91ff00
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -1083,6 +1083,14 @@ static char *get_modinfo(const struct load_info *info, const char *tag)
	return get_next_modinfo(info, tag, NULL);
}

static bool verify_module_namespace(const char *namespace, const char *modname)
{
	const char *prefix = "module:";

	return strstarts(namespace, prefix) &&
	       !strcmp(namespace + strlen(prefix), modname);
}

static int verify_namespace_is_imported(const struct load_info *info,
					const struct kernel_symbol *sym,
					struct module *mod)
@@ -1092,6 +1100,10 @@ static int verify_namespace_is_imported(const struct load_info *info,

	namespace = kernel_symbol_namespace(sym);
	if (namespace && namespace[0]) {

		if (verify_module_namespace(namespace, mod->name))
			return 0;

		for_each_modinfo_entry(imported_namespace, info, "import_ns") {
			if (strcmp(namespace, imported_namespace) == 0)
				return 0;
@@ -1659,15 +1671,30 @@ static void module_license_taint_check(struct module *mod, const char *license)
	}
}

static void setup_modinfo(struct module *mod, struct load_info *info)
static int setup_modinfo(struct module *mod, struct load_info *info)
{
	const struct module_attribute *attr;
	char *imported_namespace;
	int i;

	for (i = 0; (attr = modinfo_attrs[i]); i++) {
		if (attr->setup)
			attr->setup(mod, get_modinfo(info, attr->attr.name));
	}

	for_each_modinfo_entry(imported_namespace, info, "import_ns") {
		/*
		 * 'module:' prefixed namespaces are implicit, disallow
		 * explicit imports.
		 */
		if (strstarts(imported_namespace, "module:")) {
			pr_err("%s: module tries to import module namespace: %s\n",
			       mod->name, imported_namespace);
			return -EPERM;
		}
	}

	return 0;
}

static void free_modinfo(struct module *mod)
@@ -3335,7 +3362,9 @@ static int load_module(struct load_info *info, const char __user *uargs,
		goto free_unload;

	/* Set up MODINFO_ATTR fields */
	setup_modinfo(mod, info);
	err = setup_modinfo(mod, info);
	if (err)
		goto free_modinfo;

	/* Fix up syms, so that st_value is a pointer to location. */
	err = simplify_symbols(mod, info);
+10 −1
Original line number Diff line number Diff line
@@ -1682,6 +1682,14 @@ void buf_write(struct buffer *buf, const char *s, int len)
	buf->pos += len;
}

static bool verify_module_namespace(const char *namespace, const char *modname)
{
	const char *prefix = "module:";

	return strstarts(namespace, prefix) &&
	       !strcmp(namespace + strlen(prefix), modname);
}

static void check_exports(struct module *mod)
{
	struct symbol *s, *exp;
@@ -1709,7 +1717,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);