mm: move MAP_SYNC to asm-generic/mman-common.h
[linux-2.6-block.git] / kernel / module.c
index 0b9aa8ab89f08a3cf8474a7b56a46325a05b0ed5..a2cee14a83f360b8300503f4e5c338d0105c8056 100644 (file)
@@ -1,20 +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.
 
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 #include <linux/export.h>
 #include <linux/extable.h>
@@ -98,6 +86,10 @@ DEFINE_MUTEX(module_mutex);
 EXPORT_SYMBOL_GPL(module_mutex);
 static LIST_HEAD(modules);
 
+/* Work queue for freeing init sections in success case */
+static struct work_struct init_free_wq;
+static struct llist_head init_free_list;
+
 #ifdef CONFIG_MODULES_TREE_LOOKUP
 
 /*
@@ -286,6 +278,11 @@ bool is_module_sig_enforced(void)
 }
 EXPORT_SYMBOL(is_module_sig_enforced);
 
+void set_module_sig_enforced(void)
+{
+       sig_enforce = true;
+}
+
 /* Block module loading/unloading? */
 int modules_disabled = 0;
 core_param(nomodule, modules_disabled, bint, 0);
@@ -1949,9 +1946,16 @@ void module_enable_ro(const struct module *mod, bool after_init)
        if (!rodata_enabled)
                return;
 
+       set_vm_flush_reset_perms(mod->core_layout.base);
+       set_vm_flush_reset_perms(mod->init_layout.base);
        frob_text(&mod->core_layout, set_memory_ro);
+       frob_text(&mod->core_layout, set_memory_x);
+
        frob_rodata(&mod->core_layout, set_memory_ro);
+
        frob_text(&mod->init_layout, set_memory_ro);
+       frob_text(&mod->init_layout, set_memory_x);
+
        frob_rodata(&mod->init_layout, set_memory_ro);
 
        if (after_init)
@@ -1967,15 +1971,6 @@ static void module_enable_nx(const struct module *mod)
        frob_writable_data(&mod->init_layout, set_memory_nx);
 }
 
-static void module_disable_nx(const struct module *mod)
-{
-       frob_rodata(&mod->core_layout, set_memory_x);
-       frob_ro_after_init(&mod->core_layout, set_memory_x);
-       frob_writable_data(&mod->core_layout, set_memory_x);
-       frob_rodata(&mod->init_layout, set_memory_x);
-       frob_writable_data(&mod->init_layout, set_memory_x);
-}
-
 /* Iterate through all modules and set each module's text as RW */
 void set_all_modules_text_rw(void)
 {
@@ -2019,23 +2014,8 @@ void set_all_modules_text_ro(void)
        }
        mutex_unlock(&module_mutex);
 }
-
-static void disable_ro_nx(const struct module_layout *layout)
-{
-       if (rodata_enabled) {
-               frob_text(layout, set_memory_rw);
-               frob_rodata(layout, set_memory_rw);
-               frob_ro_after_init(layout, set_memory_rw);
-       }
-       frob_rodata(layout, set_memory_x);
-       frob_ro_after_init(layout, set_memory_x);
-       frob_writable_data(layout, set_memory_x);
-}
-
 #else
-static void disable_ro_nx(const struct module_layout *layout) { }
 static void module_enable_nx(const struct module *mod) { }
-static void module_disable_nx(const struct module *mod) { }
 #endif
 
 #ifdef CONFIG_LIVEPATCH
@@ -2115,6 +2095,11 @@ static void free_module_elf(struct module *mod)
 
 void __weak module_memfree(void *module_region)
 {
+       /*
+        * This memory may be RO, and freeing RO memory in an interrupt is not
+        * supported by vmalloc.
+        */
+       WARN_ON(in_interrupt());
        vfree(module_region);
 }
 
@@ -2166,7 +2151,6 @@ static void free_module(struct module *mod)
        mutex_unlock(&module_mutex);
 
        /* This may be empty, but that's OK */
-       disable_ro_nx(&mod->init_layout);
        module_arch_freeing_init(mod);
        module_memfree(mod->init_layout.base);
        kfree(mod->args);
@@ -2176,7 +2160,6 @@ static void free_module(struct module *mod)
        lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
 
        /* Finally, free the core (containing the module structure) */
-       disable_ro_nx(&mod->core_layout);
        module_memfree(mod->core_layout.base);
 }
 
@@ -2647,6 +2630,8 @@ static void layout_symtab(struct module *mod, struct load_info *info)
        info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1);
        info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
        mod->core_layout.size += strtab_size;
+       info->core_typeoffs = mod->core_layout.size;
+       mod->core_layout.size += ndst * sizeof(char);
        mod->core_layout.size = debug_align(mod->core_layout.size);
 
        /* Put string table section at end of init part of module. */
@@ -2660,6 +2645,8 @@ static void layout_symtab(struct module *mod, struct load_info *info)
                                      __alignof__(struct mod_kallsyms));
        info->mod_kallsyms_init_off = mod->init_layout.size;
        mod->init_layout.size += sizeof(struct mod_kallsyms);
+       info->init_typeoffs = mod->init_layout.size;
+       mod->init_layout.size += nsrc * sizeof(char);
        mod->init_layout.size = debug_align(mod->init_layout.size);
 }
 
@@ -2683,20 +2670,23 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
        mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
        /* Make sure we get permanent strtab: don't use info->strtab. */
        mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
+       mod->kallsyms->typetab = mod->init_layout.base + info->init_typeoffs;
 
-       /* Set types up while we still have access to sections. */
-       for (i = 0; i < mod->kallsyms->num_symtab; i++)
-               mod->kallsyms->symtab[i].st_size
-                       = elf_type(&mod->kallsyms->symtab[i], info);
-
-       /* Now populate the cut down core kallsyms for after init. */
+       /*
+        * Now populate the cut down core kallsyms for after init
+        * and set types up while we still have access to sections.
+        */
        mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
        mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
+       mod->core_kallsyms.typetab = mod->core_layout.base + info->core_typeoffs;
        src = mod->kallsyms->symtab;
        for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
+               mod->kallsyms->typetab[i] = elf_type(src + i, info);
                if (i == 0 || is_livepatch_module(mod) ||
                    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
                                   info->index.pcpu)) {
+                       mod->core_kallsyms.typetab[ndst] =
+                           mod->kallsyms->typetab[i];
                        dst[ndst] = src[i];
                        dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
                        s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
@@ -3093,6 +3083,11 @@ static int find_module_sections(struct module *mod, struct load_info *info)
                                             sizeof(*mod->tracepoints_ptrs),
                                             &mod->num_tracepoints);
 #endif
+#ifdef CONFIG_TREE_SRCU
+       mod->srcu_struct_ptrs = section_objs(info, "___srcu_struct_ptrs",
+                                            sizeof(*mod->srcu_struct_ptrs),
+                                            &mod->num_srcu_structs);
+#endif
 #ifdef CONFIG_BPF_EVENTS
        mod->bpf_raw_events = section_objs(info, "__bpf_raw_tp_map",
                                           sizeof(*mod->bpf_raw_events),
@@ -3415,16 +3410,33 @@ static void do_mod_ctors(struct module *mod)
 
 /* For freeing module_init on success, in case kallsyms traversing */
 struct mod_initfree {
-       struct rcu_head rcu;
+       struct llist_node node;
        void *module_init;
 };
 
-static void do_free_init(struct rcu_head *head)
+static void do_free_init(struct work_struct *w)
 {
-       struct mod_initfree *m = container_of(head, struct mod_initfree, rcu);
-       module_memfree(m->module_init);
-       kfree(m);
+       struct llist_node *pos, *n, *list;
+       struct mod_initfree *initfree;
+
+       list = llist_del_all(&init_free_list);
+
+       synchronize_rcu();
+
+       llist_for_each_safe(pos, n, list) {
+               initfree = container_of(pos, struct mod_initfree, node);
+               module_memfree(initfree->module_init);
+               kfree(initfree);
+       }
+}
+
+static int __init modules_wq_init(void)
+{
+       INIT_WORK(&init_free_wq, do_free_init);
+       init_llist_head(&init_free_list);
+       return 0;
 }
+module_init(modules_wq_init);
 
 /*
  * This is where the real work happens.
@@ -3502,7 +3514,6 @@ static noinline int do_init_module(struct module *mod)
 #endif
        module_enable_ro(mod, true);
        mod_tree_remove_init(mod);
-       disable_ro_nx(&mod->init_layout);
        module_arch_freeing_init(mod);
        mod->init_layout.base = NULL;
        mod->init_layout.size = 0;
@@ -3513,14 +3524,18 @@ static noinline int do_init_module(struct module *mod)
         * We want to free module_init, but be aware that kallsyms may be
         * walking this with preempt disabled.  In all the failure paths, we
         * call synchronize_rcu(), but we don't want to slow down the success
-        * path, so use actual RCU here.
+        * path. module_memfree() cannot be called in an interrupt, so do the
+        * work and call synchronize_rcu() in a work queue.
+        *
         * Note that module_alloc() on most architectures creates W+X page
         * mappings which won't be cleaned up until do_free_init() runs.  Any
         * code such as mark_rodata_ro() which depends on those mappings to
         * be cleaned up needs to sync with the queued work - ie
         * rcu_barrier()
         */
-       call_rcu(&freeinit->rcu, do_free_init);
+       if (llist_add(&freeinit->node, &init_free_list))
+               schedule_work(&init_free_wq);
+
        mutex_unlock(&module_mutex);
        wake_up_all(&module_wq);
 
@@ -3817,10 +3832,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
        module_bug_cleanup(mod);
        mutex_unlock(&module_mutex);
 
-       /* we can't deallocate the module until we clear memory protection */
-       module_disable_ro(mod);
-       module_disable_nx(mod);
-
  ddebug_cleanup:
        ftrace_release_mod(mod);
        dynamic_debug_remove(mod, info->debug);
@@ -4080,7 +4091,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
                        const Elf_Sym *sym = &kallsyms->symtab[symnum];
 
                        *value = kallsyms_symbol_value(sym);
-                       *type = sym->st_size;
+                       *type = kallsyms->typetab[symnum];
                        strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
                        strlcpy(module_name, mod->name, MODULE_NAME_LEN);
                        *exported = is_exported(name, *value, mod);