]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
module: Extend the module namespace parsing
authorPeter Zijlstra <peterz@infradead.org>
Fri, 2 May 2025 14:12:07 +0000 (16:12 +0200)
committerMasahiro Yamada <masahiroy@kernel.org>
Sun, 25 May 2025 09:12:03 +0000 (18:12 +0900)
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 <peterz@infradead.org>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
kernel/module/main.c
scripts/mod/modpost.c

index 5c5e725597e18e5dd7fcbb38d8951769aa992037..e4b6968dc3082787eb5c11983033bbf5c388acec 100644 (file)
@@ -1083,12 +1083,44 @@ static char *get_modinfo(const struct load_info *info, const char *tag)
        return get_next_modinfo(info, tag, NULL);
 }
 
+/**
+ * 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 int verify_namespace_is_imported(const struct load_info *info,
index c9ff4db26edbde72f185d4eef359ba4fc8205d95..16a69a1298058bb0b239386ef63438dfee04c529 100644 (file)
@@ -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)