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: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
This commit is contained in:
Peter Zijlstra
2025-05-02 16:12:06 +02:00
committed by Masahiro Yamada
parent 6b91ff002c
commit 520b1a147d
2 changed files with 41 additions and 3 deletions

View File

@@ -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);