Merge tag 'kbuild-v6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

 - Add support for the EXPORT_SYMBOL_GPL_FOR_MODULES() macro, which
   exports a symbol only to specified modules

 - Improve ABI handling in gendwarfksyms

 - Forcibly link lib-y objects to vmlinux even if CONFIG_MODULES=n

 - Add checkers for redundant or missing <linux/export.h> inclusion

 - Deprecate the extra-y syntax

 - Fix a genksyms bug when including enum constants from *.symref files

* tag 'kbuild-v6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (28 commits)
  genksyms: Fix enum consts from a reference affecting new values
  arch: use always-$(KBUILD_BUILTIN) for vmlinux.lds
  kbuild: set y instead of 1 to KBUILD_{BUILTIN,MODULES}
  efi/libstub: use 'targets' instead of extra-y in Makefile
  module: make __mod_device_table__* symbols static
  scripts/misc-check: check unnecessary #include <linux/export.h> when W=1
  scripts/misc-check: check missing #include <linux/export.h> when W=1
  scripts/misc-check: add double-quotes to satisfy shellcheck
  kbuild: move W=1 check for scripts/misc-check to top-level Makefile
  scripts/tags.sh: allow to use alternative ctags implementation
  kconfig: introduce menu type enum
  docs: symbol-namespaces: fix reST warning with literal block
  kbuild: link lib-y objects to vmlinux forcibly even when CONFIG_MODULES=n
  tinyconfig: enable CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
  docs/core-api/symbol-namespaces: drop table of contents and section numbering
  modpost: check forbidden MODULE_IMPORT_NS("module:") at compile time
  kbuild: move kbuild syntax processing to scripts/Makefile.build
  Makefile: remove dependency on archscripts for header installation
  Documentation/kbuild: Add new gendwarfksyms kABI rules
  Documentation/kbuild: Drop section numbers
  ...
This commit is contained in:
Linus Torvalds
2025-06-07 10:05:35 -07:00
49 changed files with 919 additions and 335 deletions

View File

@@ -169,6 +169,30 @@ static inline void add_taint_module(struct module *mod, unsigned flag,
set_bit(flag, &mod->taints);
}
/*
* Like strncmp(), except s/-/_/g as per scripts/Makefile.lib:name-fix-token rule.
*/
static int mod_strncmp(const char *str_a, const char *str_b, size_t n)
{
for (int i = 0; i < n; i++) {
char a = str_a[i];
char b = str_b[i];
int d;
if (a == '-') a = '_';
if (b == '-') b = '_';
d = a - b;
if (d)
return d;
if (!a)
break;
}
return 0;
}
/*
* A thread that wants to hold a reference to a module only while it
* is running can call this to safely exit.
@@ -1083,6 +1107,46 @@ 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;
glob = false;
if (sep[-1] == '*') {
len--;
glob = true;
}
if (*sep)
sep++;
if (mod_strncmp(namespace, modname, len) == 0 && (glob || len == modlen))
return true;
}
return false;
}
static int verify_namespace_is_imported(const struct load_info *info,
const struct kernel_symbol *sym,
struct module *mod)
@@ -1092,6 +1156,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;
@@ -1658,15 +1726,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)
@@ -3323,7 +3406,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);