From 6b91ff002c67b2502009f99115c4b7fe5b7b8248 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 2 May 2025 16:12:05 +0200 Subject: modpost: Use for() loop Slight cleanup by using a for() loop instead of while(). This makes it clearer what is the iteration and what is the actual work done. Signed-off-by: Peter Zijlstra Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index be89921d60b6..2d1c059bf6cf 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1595,12 +1595,10 @@ 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)) add_namespace(&mod->imported_namespaces, namespace); - namespace = get_next_modinfo(&info, "import_ns", - namespace); - } if (!get_modinfo(&info, "description")) warn("missing MODULE_DESCRIPTION() in %s\n", modname); -- cgit v1.2.3 From 520b1a147d918eb07132c847ad5598a17d3ff7ca Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 2 May 2025 16:12:06 +0200 Subject: 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 Reviewed-by: Petr Pavlu Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2d1c059bf6cf..c9ff4db26edb 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -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); -- cgit v1.2.3 From 754f8733fc09dd92093cfbd34fa71a42d152b250 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 2 May 2025 16:12:07 +0200 Subject: module: Extend the module namespace parsing Instead of only accepting "module:${name}", extend it with a comma separated list of module names and add tail glob support. That is, something like: "module:foo-*,bar" is now possible. Signed-off-by: Peter Zijlstra Reviewed-by: Petr Pavlu Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c9ff4db26edb..16a69a129805 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1682,12 +1682,44 @@ 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; - return strstarts(namespace, prefix) && - !strcmp(namespace + strlen(prefix), modname); + 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) -- cgit v1.2.3 From 9c036cfbb75bb58ecce589f547fdb8af153493a6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 22 May 2025 16:17:20 +0900 Subject: modpost: check forbidden MODULE_IMPORT_NS("module:") at compile time Explicitly adding MODULE_IMPORT_NS("module:...") is not allowed. Currently, this is only checked at run time. That is, when such a module is loaded, an error message like the following is shown: foo: module tries to import module namespace: module:bar Obviously, checking this at compile time improves usability. In such a case, modpost will report the following error at compile time: ERROR: modpost: foo: explicitly importing namespace "module:bar" is not allowed. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 16a69a129805..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; @@ -1597,8 +1599,13 @@ static void read_symbols(const char *modname) for (namespace = get_modinfo(&info, "import_ns"); namespace; - namespace = get_next_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); + } if (!get_modinfo(&info, "description")) warn("missing MODULE_DESCRIPTION() in %s\n", modname); -- cgit v1.2.3