Skip to content

Commit 520b1a1

Browse files
Peter Zijlstramasahir0y
authored andcommitted
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 <[email protected]> Reviewed-by: Petr Pavlu <[email protected]> Signed-off-by: Masahiro Yamada <[email protected]>
1 parent 6b91ff0 commit 520b1a1

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

kernel/module/main.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,14 @@ static char *get_modinfo(const struct load_info *info, const char *tag)
10831083
return get_next_modinfo(info, tag, NULL);
10841084
}
10851085

1086+
static bool verify_module_namespace(const char *namespace, const char *modname)
1087+
{
1088+
const char *prefix = "module:";
1089+
1090+
return strstarts(namespace, prefix) &&
1091+
!strcmp(namespace + strlen(prefix), modname);
1092+
}
1093+
10861094
static int verify_namespace_is_imported(const struct load_info *info,
10871095
const struct kernel_symbol *sym,
10881096
struct module *mod)
@@ -1092,6 +1100,10 @@ static int verify_namespace_is_imported(const struct load_info *info,
10921100

10931101
namespace = kernel_symbol_namespace(sym);
10941102
if (namespace && namespace[0]) {
1103+
1104+
if (verify_module_namespace(namespace, mod->name))
1105+
return 0;
1106+
10951107
for_each_modinfo_entry(imported_namespace, info, "import_ns") {
10961108
if (strcmp(namespace, imported_namespace) == 0)
10971109
return 0;
@@ -1659,15 +1671,30 @@ static void module_license_taint_check(struct module *mod, const char *license)
16591671
}
16601672
}
16611673

1662-
static void setup_modinfo(struct module *mod, struct load_info *info)
1674+
static int setup_modinfo(struct module *mod, struct load_info *info)
16631675
{
16641676
const struct module_attribute *attr;
1677+
char *imported_namespace;
16651678
int i;
16661679

16671680
for (i = 0; (attr = modinfo_attrs[i]); i++) {
16681681
if (attr->setup)
16691682
attr->setup(mod, get_modinfo(info, attr->attr.name));
16701683
}
1684+
1685+
for_each_modinfo_entry(imported_namespace, info, "import_ns") {
1686+
/*
1687+
* 'module:' prefixed namespaces are implicit, disallow
1688+
* explicit imports.
1689+
*/
1690+
if (strstarts(imported_namespace, "module:")) {
1691+
pr_err("%s: module tries to import module namespace: %s\n",
1692+
mod->name, imported_namespace);
1693+
return -EPERM;
1694+
}
1695+
}
1696+
1697+
return 0;
16711698
}
16721699

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

33373364
/* Set up MODINFO_ATTR fields */
3338-
setup_modinfo(mod, info);
3365+
err = setup_modinfo(mod, info);
3366+
if (err)
3367+
goto free_modinfo;
33393368

33403369
/* Fix up syms, so that st_value is a pointer to location. */
33413370
err = simplify_symbols(mod, info);

scripts/mod/modpost.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,14 @@ void buf_write(struct buffer *buf, const char *s, int len)
16821682
buf->pos += len;
16831683
}
16841684

1685+
static bool verify_module_namespace(const char *namespace, const char *modname)
1686+
{
1687+
const char *prefix = "module:";
1688+
1689+
return strstarts(namespace, prefix) &&
1690+
!strcmp(namespace + strlen(prefix), modname);
1691+
}
1692+
16851693
static void check_exports(struct module *mod)
16861694
{
16871695
struct symbol *s, *exp;
@@ -1709,7 +1717,8 @@ static void check_exports(struct module *mod)
17091717

17101718
basename = get_basename(mod->name);
17111719

1712-
if (!contains_namespace(&mod->imported_namespaces, exp->namespace)) {
1720+
if (!verify_module_namespace(exp->namespace, basename) &&
1721+
!contains_namespace(&mod->imported_namespaces, exp->namespace)) {
17131722
modpost_log(!allow_missing_ns_imports,
17141723
"module %s uses symbol %s from namespace %s, but does not import it.\n",
17151724
basename, exp->name, exp->namespace);

0 commit comments

Comments
 (0)