mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user