]> Git Repo - J-linux.git/commitdiff
Merge tag 'modules-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu...
authorLinus Torvalds <[email protected]>
Thu, 17 Dec 2020 21:01:31 +0000 (13:01 -0800)
committerLinus Torvalds <[email protected]>
Thu, 17 Dec 2020 21:01:31 +0000 (13:01 -0800)
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

1  2 
include/linux/module.h
kernel/module.c
kernel/params.c

diff --combined include/linux/module.h
index c4e7a887f469b30184287866c20155fc035969fa,e7a619c2457e736598c85789b23eaffd33545178..7a0bcb5b1ffccdd22e2a56a72b3e991db1d08aa4
@@@ -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 c3a9e972d3b25e1b139c7f2a9c67010c0f63b048,e1dd0df57244dd2f21160cc2476f3eaa95f9a00a..4bf30e4b3eaaa1ad884aed1d7c9671089bc888da
@@@ -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
        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)
  {
  
        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;
                                     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);
                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 164d79330849a0a3c213b2802ac41b02eb96f5a6,aa7d6f2213f10dece53aba3c6a8a2af4e339e319..2daa2780a92cfde5cce2369301611c7070e156b8
@@@ -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);
This page took 0.092056 seconds and 4 git commands to generate.