The following commit has been merged in the master branch: commit 312dcaf967219effe0483785f24e4072a5bed9a5 Merge: 6daa90439e91bb9a71864b02f7d0af8587ea889a 38dc717e97153e46375ee21797aa54777e5498f3 Author: Linus Torvalds torvalds@linux-foundation.org Date: Thu Dec 17 13:01:31 2020 -0800
Merge tag 'modules-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux
Pull modules updates from Jessica Yu: "Summary of modules changes for the 5.11 merge window:
- Fix a race condition between systemd/udev and the module loader.
The module loader was sending a uevent before the module was fully initialized (i.e., before its init function has been called). This means udev can start processing the module uevent before the module has finished initializing, and some udev rules expect that the module has initialized already upon receiving the uevent.
This resulted in some systemd mount units failing if udev processes the event faster than the module can finish init. This is fixed by delaying the uevent until after the module has called its init routine.
- Make the linker array sections for kernel params and module version attributes more robust by switching to use the alignment of the type in question.
Namely, linker section arrays will be constructed using the alignment required by the struct (using __alignof__()) as opposed to a specific value such as sizeof(void *) or sizeof(long). This is less likely to cause breakages should the size of the type ever change (Johan Hovold)
- Fix module state inconsistency by setting it back to GOING when a module fails to load and is on its way out (Miroslav Benes)
- Some comment and code cleanups (Sergey Shtylyov)"
* tag 'modules-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux: module: delay kobject uevent until after module init call module: drop semicolon from version macro init: use type alignment for kernel parameters params: clean up module-param macros params: use type alignment for kernel parameters params: drop redundant "unused" attributes module: simplify version-attribute handling module: drop version-attribute alignment module: fix comment style module: add more 'kernel-doc' comments module: fix up 'kernel-doc' comments module: only handle errors with the *switch* statement in module_sig_check() module: avoid *goto*s in module_sig_check() module: merge repetitive strings in module_sig_check() module: set MODULE_STATE_GOING state when a module fails to load
diff --combined include/linux/module.h index c4e7a887f469,e7a619c2457e..7a0bcb5b1ffc --- a/include/linux/module.h +++ b/include/linux/module.h @@@ -66,7 -66,7 +66,7 @@@ struct module_version_attribute struct module_attribute mattr; const char *module_name; const char *version; - } __attribute__ ((__aligned__(sizeof(void *)))); + };
extern ssize_t __modver_version_show(struct module_attribute *, struct module_kobject *, char *); @@@ -266,20 -266,20 +266,20 @@@ extern typeof(name) __mod_##type##__##n #else #define MODULE_VERSION(_version) \ MODULE_INFO(version, _version); \ - static struct module_version_attribute ___modver_attr = { \ - .mattr = { \ - .attr = { \ - .name = "version", \ - .mode = S_IRUGO, \ + static struct module_version_attribute __modver_attr \ + __used __section("__modver") \ + __aligned(__alignof__(struct module_version_attribute)) \ + = { \ + .mattr = { \ + .attr = { \ + .name = "version", \ + .mode = S_IRUGO, \ + }, \ + .show = __modver_version_show, \ }, \ - .show = __modver_version_show, \ - }, \ - .module_name = KBUILD_MODNAME, \ - .version = _version, \ - }; \ - static const struct module_version_attribute \ - __used __section("__modver") \ - * __moduleparam_const __modver_attr = &___modver_attr + .module_name = KBUILD_MODNAME, \ + .version = _version, \ + } #endif
/* Optional firmware file (or files) needed by the module @@@ -475,10 -475,6 +475,10 @@@ struct module unsigned int num_bpf_raw_events; struct bpf_raw_event_map *bpf_raw_events; #endif +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES + unsigned int btf_data_size; + void *btf_data; +#endif #ifdef CONFIG_JUMP_LABEL struct jump_entry *jump_entries; unsigned int num_jump_entries; @@@ -744,7 -740,7 +744,7 @@@ static inline bool within_module(unsign }
/* Get/put a kernel symbol (calls should be symmetric) */ -#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) +#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak,visibility("hidden"))); &(x); }) #define symbol_put(x) do { } while (0) #define symbol_put_addr(x) do { } while (0)
diff --combined kernel/module.c index c3a9e972d3b2,e1dd0df57244..4bf30e4b3eaa --- a/kernel/module.c +++ b/kernel/module.c @@@ -1,9 -1,8 +1,8 @@@ // SPDX-License-Identifier: GPL-2.0-or-later /* - Copyright (C) 2002 Richard Henderson - Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM. - - */ + * Copyright (C) 2002 Richard Henderson + * Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM. + */
#define INCLUDE_VERMAGIC
@@@ -86,7 -85,8 +85,8 @@@ * 1) List of modules (also safely readable with preempt_disable), * 2) module_use links, * 3) module_addr_min/module_addr_max. - * (delete and add uses RCU list operations). */ + * (delete and add uses RCU list operations). + */ DEFINE_MUTEX(module_mutex); EXPORT_SYMBOL_GPL(module_mutex); static LIST_HEAD(modules); @@@ -380,35 -380,6 +380,35 @@@ static void *section_objs(const struct return (void *)info->sechdrs[sec].sh_addr; }
+/* Find a module section: 0 means not found. Ignores SHF_ALLOC flag. */ +static unsigned int find_any_sec(const struct load_info *info, const char *name) +{ + unsigned int i; + + for (i = 1; i < info->hdr->e_shnum; i++) { + Elf_Shdr *shdr = &info->sechdrs[i]; + if (strcmp(info->secstrings + shdr->sh_name, name) == 0) + return i; + } + return 0; +} + +/* + * Find a module section, or NULL. Fill in number of "objects" in section. + * Ignores SHF_ALLOC flag. + */ +static __maybe_unused void *any_section_objs(const struct load_info *info, + const char *name, + size_t object_size, + unsigned int *num) +{ + unsigned int sec = find_any_sec(info, name); + + /* Section 0 has sh_addr 0 and sh_size 0. */ + *num = info->sechdrs[sec].sh_size / object_size; + return (void *)info->sechdrs[sec].sh_addr; +} + /* Provided by the linker */ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; @@@ -615,8 -586,10 +615,10 @@@ static bool find_exported_symbol_in_sec return false; }
- /* Find an exported symbol and return it, along with, (optional) crc and - * (optional) module which owns it. Needs preempt disabled or module_mutex. */ + /* + * Find an exported symbol and return it, along with, (optional) crc and + * (optional) module which owns it. Needs preempt disabled or module_mutex. + */ static const struct kernel_symbol *find_symbol(const char *name, struct module **owner, const s32 **crc, @@@ -756,13 -729,12 +758,12 @@@ bool __is_module_percpu_address(unsigne }
/** - * is_module_percpu_address - test whether address is from module static percpu + * is_module_percpu_address() - test whether address is from module static percpu * @addr: address to test * * Test whether @addr belongs to module static percpu area. * - * RETURNS: - * %true if @addr is from module static percpu area + * Return: %true if @addr is from module static percpu area */ bool is_module_percpu_address(unsigned long addr) { @@@ -986,11 -958,10 +987,10 @@@ static int try_stop_module(struct modul }
/** - * module_refcount - return the refcount or -1 if unloading - * + * module_refcount() - return the refcount or -1 if unloading * @mod: the module we're checking * - * Returns: + * Return: * -1 if the module is in the process of unloading * otherwise the number of references in the kernel to the module */ @@@ -1675,8 -1646,10 +1675,10 @@@ static void remove_sect_attrs(struct mo if (mod->sect_attrs) { sysfs_remove_group(&mod->mkobj.kobj, &mod->sect_attrs->grp); - /* We are positive that no one is using any sect attrs - * at this point. Deallocate immediately. */ + /* + * We are positive that no one is using any sect attrs + * at this point. Deallocate immediately. + */ free_sect_attrs(mod->sect_attrs); mod->sect_attrs = NULL; } @@@ -1924,7 -1897,6 +1926,6 @@@ static int mod_sysfs_init(struct modul if (err) mod_kobject_put(mod);
- /* delay uevent until full sysfs population */ out: return err; } @@@ -1961,7 -1933,6 +1962,6 @@@ static int mod_sysfs_setup(struct modul add_sect_attrs(mod, info); add_notes_attrs(mod, info);
- kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); return 0;
out_unreg_modinfo_attrs: @@@ -2247,8 -2218,10 +2247,10 @@@ static void free_module(struct module *
mod_sysfs_teardown(mod);
- /* We leave it in list to prevent duplicate loads, but make sure - * that noone uses it while it's being deconstructed. */ + /* + * We leave it in list to prevent duplicate loads, but make sure + * that noone uses it while it's being deconstructed. + */ mutex_lock(&module_mutex); mod->state = MODULE_STATE_UNFORMED; mutex_unlock(&module_mutex); @@@ -2365,8 -2338,10 +2367,10 @@@ static int simplify_symbols(struct modu if (!strncmp(name, "__gnu_lto", 9)) break;
- /* We compiled with -fno-common. These are not - supposed to happen. */ + /* + * We compiled with -fno-common. These are not + * supposed to happen. + */ pr_debug("Common symbol: %s\n", name); pr_warn("%s: please compile with -fno-common\n", mod->name); @@@ -2469,16 -2444,20 +2473,20 @@@ static long get_offset(struct module *m return ret; }
- /* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld - might -- code, read-only data, read-write data, small data. Tally - sizes, and place the offsets into sh_entsize fields: high bit means it - belongs in init. */ + /* + * Lay out the SHF_ALLOC sections in a way not dissimilar to how ld + * might -- code, read-only data, read-write data, small data. Tally + * sizes, and place the offsets into sh_entsize fields: high bit means it + * belongs in init. + */ static void layout_sections(struct module *mod, struct load_info *info) { static unsigned long const masks[][2] = { - /* NOTE: all executable code must be the first section + /* + * NOTE: all executable code must be the first section * in this array; otherwise modify the text_size - * finder in the two loops below */ + * finder in the two loops below + */ { SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL }, { SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL }, { SHF_RO_AFTER_INIT | SHF_ALLOC, ARCH_SHF_SMALL }, @@@ -2924,40 -2903,43 +2932,43 @@@ static int module_sig_check(struct load /* We truncate the module to discard the signature */ info->len -= markerlen; err = mod_verify_sig(mod, info); + if (!err) { + info->sig_ok = true; + return 0; + } }
+ /* + * We don't permit modules to be loaded into the trusted kernels + * without a valid signature on them, but if we're not enforcing, + * certain errors are non-fatal. + */ switch (err) { - case 0: - info->sig_ok = true; - return 0; - - /* We don't permit modules to be loaded into trusted kernels - * without a valid signature on them, but if we're not - * enforcing, certain errors are non-fatal. - */ case -ENODATA: - reason = "Loading of unsigned module"; - goto decide; + reason = "unsigned module"; + break; case -ENOPKG: - reason = "Loading of module with unsupported crypto"; - goto decide; + reason = "module with unsupported crypto"; + break; case -ENOKEY: - reason = "Loading of module with unavailable key"; - decide: - if (is_module_sig_enforced()) { - pr_notice("%s: %s is rejected\n", info->name, reason); - return -EKEYREJECTED; - } - - return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); + reason = "module with unavailable key"; + break;
- /* All other errors are fatal, including nomem, unparseable - * signatures and signature check failures - even if signatures - * aren't required. - */ default: + /* + * All other errors are fatal, including lack of memory, + * unparseable signatures, and signature check failures -- + * even if signatures aren't required. + */ return err; } + + if (is_module_sig_enforced()) { + pr_notice("%s: loading of %s is rejected\n", info->name, reason); + return -EKEYREJECTED; + } + + return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); } #else /* !CONFIG_MODULE_SIG */ static int module_sig_check(struct load_info *info, int flags) @@@ -3090,8 -3072,10 +3101,10 @@@ static int rewrite_section_headers(stru return -ENOEXEC; }
- /* Mark all sections sh_addr with their address in the - temporary image. */ + /* + * Mark all sections sh_addr with their address in the + * temporary image. + */ shdr->sh_addr = (size_t)info->hdr + shdr->sh_offset;
#ifndef CONFIG_MODULE_UNLOAD @@@ -3279,9 -3263,6 +3292,9 @@@ static int find_module_sections(struct sizeof(*mod->bpf_raw_events), &mod->num_bpf_raw_events); #endif +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES + mod->btf_data = any_section_objs(info, ".BTF", 1, &mod->btf_data_size); +#endif #ifdef CONFIG_JUMP_LABEL mod->jump_entries = section_objs(info, "__jump_table", sizeof(*mod->jump_entries), @@@ -3525,9 -3506,11 +3538,11 @@@ static struct module *layout_and_alloca if (ndx) info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
- /* Determine total sizes, and put offsets in sh_entsize. For now - this is done generically; there doesn't appear to be any - special cases for the architectures. */ + /* + * Determine total sizes, and put offsets in sh_entsize. For now + * this is done generically; there doesn't appear to be any + * special cases for the architectures. + */ layout_sections(info->mod, info); layout_symtab(info->mod, info);
@@@ -3671,6 -3654,9 +3686,9 @@@ static noinline int do_init_module(stru blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_LIVE, mod);
+ /* Delay uevent until module has finished its init routine */ + kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); + /* * We need to finish all async code before the module init sequence * is done. This has potential to deadlock. For example, a newly @@@ -3709,10 -3695,6 +3727,10 @@@ mod->init_layout.ro_size = 0; mod->init_layout.ro_after_init_size = 0; mod->init_layout.text_size = 0; +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES + /* .BTF is not SHF_ALLOC and will get removed, so sanitize pointer */ + mod->btf_data = NULL; +#endif /* * We want to free module_init, but be aware that kallsyms may be * walking this with preempt disabled. In all the failure paths, we @@@ -3815,8 -3797,10 +3833,10 @@@ static int complete_formation(struct mo module_enable_nx(mod); module_enable_x(mod);
- /* Mark state as coming so strong_try_module_get() ignores us, - * but kallsyms etc. can see us. */ + /* + * Mark state as coming so strong_try_module_get() ignores us, + * but kallsyms etc. can see us. + */ mod->state = MODULE_STATE_COMING; mutex_unlock(&module_mutex);
@@@ -3863,8 -3847,10 +3883,10 @@@ static int unknown_module_param_cb(cha return 0; }
- /* Allocate and load the module: note that size of section 0 is always - zero, and we rely on this for optional sections. */ + /* + * Allocate and load the module: note that size of section 0 is always + * zero, and we rely on this for optional sections. + */ static int load_module(struct load_info *info, const char __user *uargs, int flags) { @@@ -3938,8 -3924,10 +3960,10 @@@
init_param_lock(mod);
- /* Now we've got everything in the final locations, we can - * find optional sections. */ + /* + * Now we've got everything in the final locations, we can + * find optional sections. + */ err = find_module_sections(mod, info); if (err) goto free_unload; @@@ -4027,6 -4015,7 +4051,7 @@@ MODULE_STATE_GOING, mod); klp_module_going(mod); bug_cleanup: + mod->state = MODULE_STATE_GOING; /* module_bug_cleanup needs module_mutex protection */ mutex_lock(&module_mutex); module_bug_cleanup(mod); @@@ -4152,8 -4141,10 +4177,10 @@@ static const char *find_kallsyms_symbol
bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
- /* Scan for closest preceding symbol, and next symbol. (ELF - starts real symbols at 1). */ + /* + * Scan for closest preceding symbol, and next symbol. (ELF + * starts real symbols at 1). + */ for (i = 1; i < kallsyms->num_symtab; i++) { const Elf_Sym *sym = &kallsyms->symtab[i]; unsigned long thisval = kallsyms_symbol_value(sym); @@@ -4161,8 -4152,10 +4188,10 @@@ if (sym->st_shndx == SHN_UNDEF) continue;
- /* We ignore unnamed symbols: they're uninformative - * and inserted at a whim. */ + /* + * We ignore unnamed symbols: they're uninformative + * and inserted at a whim. + */ if (*kallsyms_symbol_name(kallsyms, i) == '\0' || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) continue; @@@ -4192,8 -4185,10 +4221,10 @@@ void * __weak dereference_module_functi return ptr; }
- /* For kallsyms to ask for address resolution. NULL means not found. Careful - * not to lock to avoid deadlock on oopses, simply disable preemption. */ + /* + * For kallsyms to ask for address resolution. NULL means not found. Careful + * not to lock to avoid deadlock on oopses, simply disable preemption. + */ const char *module_address_lookup(unsigned long addr, unsigned long *size, unsigned long *offset, @@@ -4451,11 -4446,12 +4482,12 @@@ static int m_show(struct seq_file *m, v return 0; }
- /* Format: modulename size refcount deps address - - Where refcount is a number or -, and deps is a comma-separated list - of depends or -. - */ + /* + * Format: modulename size refcount deps address + * + * Where refcount is a number or -, and deps is a comma-separated list + * of depends or -. + */ static const struct seq_operations modules_op = { .start = m_start, .next = m_next, @@@ -4525,8 -4521,8 +4557,8 @@@ out return e; }
- /* - * is_module_address - is this address inside a module? + /** + * is_module_address() - is this address inside a module? * @addr: the address to check. * * See is_module_text_address() if you simply want to see if the address @@@ -4543,8 -4539,8 +4575,8 @@@ bool is_module_address(unsigned long ad return ret; }
- /* - * __module_address - get the module which contains an address. + /** + * __module_address() - get the module which contains an address. * @addr: the address. * * Must be called with preempt disabled or module mutex held so that @@@ -4568,8 -4564,8 +4600,8 @@@ struct module *__module_address(unsigne return mod; }
- /* - * is_module_text_address - is this address inside module code? + /** + * is_module_text_address() - is this address inside module code? * @addr: the address to check. * * See is_module_address() if you simply want to see if the address is @@@ -4587,8 -4583,8 +4619,8 @@@ bool is_module_text_address(unsigned lo return ret; }
- /* - * __module_text_address - get the module whose code contains an address. + /** + * __module_text_address() - get the module whose code contains an address. * @addr: the address. * * Must be called with preempt disabled or module mutex held so that @@@ -4627,8 -4623,10 +4659,10 @@@ void print_modules(void }
#ifdef CONFIG_MODVERSIONS - /* Generate the signature for all relevant module structures here. - * If these change, we don't want to try to parse the module. */ + /* + * Generate the signature for all relevant module structures here. + * If these change, we don't want to try to parse the module. + */ void module_layout(struct module *mod, struct modversion_info *ver, struct kernel_param *kp, diff --combined kernel/params.c index 164d79330849,aa7d6f2213f1..2daa2780a92c --- a/kernel/params.c +++ b/kernel/params.c @@@ -530,7 -530,7 +530,7 @@@ struct module_param_attr { unsigned int num; struct attribute_group grp; - struct param_attribute attrs[0]; + struct param_attribute attrs[]; };
#ifdef CONFIG_SYSFS @@@ -843,18 -843,16 +843,16 @@@ ssize_t __modver_version_show(struct mo return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version); }
- extern const struct module_version_attribute *__start___modver[]; - extern const struct module_version_attribute *__stop___modver[]; + extern const struct module_version_attribute __start___modver[]; + extern const struct module_version_attribute __stop___modver[];
static void __init version_sysfs_builtin(void) { - const struct module_version_attribute **p; + const struct module_version_attribute *vattr; struct module_kobject *mk; int err;
- for (p = __start___modver; p < __stop___modver; p++) { - const struct module_version_attribute *vattr = *p; - + for (vattr = __start___modver; vattr < __stop___modver; vattr++) { mk = locate_module_kobject(vattr->module_name); if (mk) { err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
linux-merge@lists.open-mesh.org