Merge commit 'v2.6.31-rc9' into tracing/core
[safe/jmp/linux-2.6] / kernel / module.c
index 784bf6d..46580ed 100644 (file)
@@ -18,6 +18,7 @@
 */
 #include <linux/module.h>
 #include <linux/moduleloader.h>
+#include <linux/ftrace_event.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
 #include <linux/fs.h>
 #include <linux/ftrace.h>
 #include <linux/async.h>
 #include <linux/percpu.h>
+#include <linux/kmemleak.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/module.h>
+
+EXPORT_TRACEPOINT_SYMBOL(module_get);
 
 #if 0
 #define DEBUGP printk
@@ -72,6 +79,9 @@ DEFINE_MUTEX(module_mutex);
 EXPORT_SYMBOL_GPL(module_mutex);
 static LIST_HEAD(modules);
 
+/* Block module loading/unloading? */
+int modules_disabled = 0;
+
 /* Waiting for a module to finish initializing? */
 static DECLARE_WAIT_QUEUE_HEAD(module_wq);
 
@@ -429,6 +439,7 @@ static void *percpu_modalloc(unsigned long size, unsigned long align,
        unsigned long extra;
        unsigned int i;
        void *ptr;
+       int cpu;
 
        if (align > PAGE_SIZE) {
                printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
@@ -458,6 +469,11 @@ static void *percpu_modalloc(unsigned long size, unsigned long align,
                        if (!split_block(i, size))
                                return NULL;
 
+               /* add the per-cpu scanning areas */
+               for_each_possible_cpu(cpu)
+                       kmemleak_alloc(ptr + per_cpu_offset(cpu), size, 0,
+                                      GFP_KERNEL);
+
                /* Mark allocated */
                pcpu_size[i] = -pcpu_size[i];
                return ptr;
@@ -472,6 +488,7 @@ static void percpu_modfree(void *freeme)
 {
        unsigned int i;
        void *ptr = __per_cpu_start + block_size(pcpu_size[0]);
+       int cpu;
 
        /* First entry is core kernel percpu data. */
        for (i = 1; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) {
@@ -483,6 +500,10 @@ static void percpu_modfree(void *freeme)
        BUG();
 
  free:
+       /* remove the per-cpu scanning areas */
+       for_each_possible_cpu(cpu)
+               kmemleak_free(freeme + per_cpu_offset(cpu));
+
        /* Merge with previous? */
        if (pcpu_size[i-1] >= 0) {
                pcpu_size[i-1] += pcpu_size[i];
@@ -777,7 +798,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
        char name[MODULE_NAME_LEN];
        int ret, forced = 0;
 
-       if (!capable(CAP_SYS_MODULE))
+       if (!capable(CAP_SYS_MODULE) || modules_disabled)
                return -EPERM;
 
        if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
@@ -893,16 +914,18 @@ void __symbol_put(const char *symbol)
 }
 EXPORT_SYMBOL(__symbol_put);
 
+/* Note this assumes addr is a function, which it currently always is. */
 void symbol_put_addr(void *addr)
 {
        struct module *modaddr;
+       unsigned long a = (unsigned long)dereference_function_descriptor(addr);
 
-       if (core_kernel_text((unsigned long)addr))
+       if (core_kernel_text(a))
                return;
 
        /* module_text_address is safe here: we're supposed to have reference
         * to module from symbol_get, so it can't go away. */
-       modaddr = __module_text_address((unsigned long)addr);
+       modaddr = __module_text_address(a);
        BUG_ON(!modaddr);
        module_put(modaddr);
 }
@@ -924,6 +947,8 @@ void module_put(struct module *module)
        if (module) {
                unsigned int cpu = get_cpu();
                local_dec(__module_ref_addr(module, cpu));
+               trace_module_put(module, _RET_IP_,
+                                local_read(__module_ref_addr(module, cpu)));
                /* Maybe they're waiting for us to drop reference? */
                if (unlikely(!module_is_live(module)))
                        wake_up_process(module->waiter);
@@ -1052,9 +1077,10 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
 {
        const unsigned long *crc;
 
-       if (!find_symbol("struct_module", NULL, &crc, true, false))
+       if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
+                        &crc, true, false))
                BUG();
-       return check_version(sechdrs, versindex, "struct_module", mod, crc);
+       return check_version(sechdrs, versindex, "module_layout", mod, crc);
 }
 
 /* First part is kernel version, which we ignore if module has crcs. */
@@ -1255,6 +1281,10 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
        struct module_notes_attrs *notes_attrs;
        struct bin_attribute *nattr;
 
+       /* failed to create section attributes, so can't create notes */
+       if (!mod->sect_attrs)
+               return;
+
        /* Count notes sections and allocate structures.  */
        notes = 0;
        for (i = 0; i < nsect; i++)
@@ -1474,6 +1504,8 @@ static int __unlink_module(void *_mod)
 /* Free a module, remove from lists, etc (must hold module_mutex). */
 static void free_module(struct module *mod)
 {
+       trace_module_free(mod);
+
        /* Delete from various lists */
        stop_machine(__unlink_module, mod, NULL);
        remove_notes_attrs(mod);
@@ -1489,9 +1521,6 @@ static void free_module(struct module *mod)
        /* Free any allocated parameters. */
        destroy_params(mod->kp, mod->num_kp);
 
-       /* release any pointers to mcount in this module */
-       ftrace_release(mod->module_core, mod->core_size);
-
        /* This may be NULL, but that's OK */
        module_free(mod, mod->module_init);
        kfree(mod->args);
@@ -1673,8 +1702,7 @@ static void layout_sections(struct module *mod,
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strncmp(secstrings + s->sh_name,
-                                      ".init", 5) == 0)
+                           || strstarts(secstrings + s->sh_name, ".init"))
                                continue;
                        s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
                        DEBUGP("\t%s\n", secstrings + s->sh_name);
@@ -1691,8 +1719,7 @@ static void layout_sections(struct module *mod,
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strncmp(secstrings + s->sh_name,
-                                      ".init", 5) != 0)
+                           || !strstarts(secstrings + s->sh_name, ".init"))
                                continue;
                        s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
                                         | INIT_OFFSET_MASK);
@@ -1825,8 +1852,7 @@ static char elf_type(const Elf_Sym *sym,
                else
                        return 'b';
        }
-       if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
-                   ".debug", strlen(".debug")) == 0)
+       if (strstarts(secstrings + sechdrs[sym->st_shndx].sh_name, ".debug"))
                return 'n';
        return '?';
 }
@@ -1881,6 +1907,36 @@ static void *module_alloc_update_bounds(unsigned long size)
        return ret;
 }
 
+#ifdef CONFIG_DEBUG_KMEMLEAK
+static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
+                                Elf_Shdr *sechdrs, char *secstrings)
+{
+       unsigned int i;
+
+       /* only scan the sections containing data */
+       kmemleak_scan_area(mod->module_core, (unsigned long)mod -
+                          (unsigned long)mod->module_core,
+                          sizeof(struct module), GFP_KERNEL);
+
+       for (i = 1; i < hdr->e_shnum; i++) {
+               if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+                       continue;
+               if (strncmp(secstrings + sechdrs[i].sh_name, ".data", 5) != 0
+                   && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0)
+                       continue;
+
+               kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr -
+                                  (unsigned long)mod->module_core,
+                                  sechdrs[i].sh_size, GFP_KERNEL);
+       }
+}
+#else
+static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr,
+                                       Elf_Shdr *sechdrs, char *secstrings)
+{
+}
+#endif
+
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
 static noinline struct module *load_module(void __user *umod,
@@ -1895,11 +1951,9 @@ static noinline struct module *load_module(void __user *umod,
        unsigned int symindex = 0;
        unsigned int strindex = 0;
        unsigned int modindex, versindex, infoindex, pcpuindex;
-       unsigned int num_mcount;
        struct module *mod;
        long err = 0;
        void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
-       unsigned long *mseg;
        mm_segment_t old_fs;
 
        DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -1912,12 +1966,6 @@ static noinline struct module *load_module(void __user *umod,
        if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
                return ERR_PTR(-ENOMEM);
 
-       /* Create stop_machine threads since the error path relies on
-        * a non-failing stop_machine call. */
-       err = stop_machine_create();
-       if (err)
-               goto free_hdr;
-
        if (copy_from_user(hdr, umod, len) != 0) {
                err = -EFAULT;
                goto free_hdr;
@@ -1958,12 +2006,9 @@ static noinline struct module *load_module(void __user *umod,
                }
 #ifndef CONFIG_MODULE_UNLOAD
                /* Don't load .exit sections */
-               if (strncmp(secstrings+sechdrs[i].sh_name, ".exit", 5) == 0)
+               if (strstarts(secstrings+sechdrs[i].sh_name, ".exit"))
                        sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 #endif
-               /* Don't keep __versions around; it's just for loading. */
-               if (strcmp(secstrings + sechdrs[i].sh_name, "__versions") == 0)
-                       sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
        }
 
        modindex = find_sec(hdr, sechdrs, secstrings,
@@ -2062,6 +2107,12 @@ static noinline struct module *load_module(void __user *umod,
 
        /* Do the allocs. */
        ptr = module_alloc_update_bounds(mod->core_size);
+       /*
+        * The pointer to this block is stored in the module structure
+        * which is inside the block. Just mark it as not being a
+        * leak.
+        */
+       kmemleak_not_leak(ptr);
        if (!ptr) {
                err = -ENOMEM;
                goto free_percpu;
@@ -2070,6 +2121,13 @@ static noinline struct module *load_module(void __user *umod,
        mod->module_core = ptr;
 
        ptr = module_alloc_update_bounds(mod->init_size);
+       /*
+        * The pointer to this block is stored in the module structure
+        * which is inside the block. This block doesn't need to be
+        * scanned as it contains data and code that will be freed
+        * after the module is initialized.
+        */
+       kmemleak_ignore(ptr);
        if (!ptr && mod->init_size) {
                err = -ENOMEM;
                goto free_core;
@@ -2100,6 +2158,7 @@ static noinline struct module *load_module(void __user *umod,
        }
        /* Module has been moved. */
        mod = (void *)sechdrs[modindex].sh_addr;
+       kmemleak_load_module(mod, hdr, sechdrs, secstrings);
 
 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
        mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),
@@ -2173,6 +2232,10 @@ static noinline struct module *load_module(void __user *umod,
        mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings,
                                            "__kcrctab_unused_gpl");
 #endif
+#ifdef CONFIG_CONSTRUCTORS
+       mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors",
+                                 sizeof(*mod->ctors), &mod->num_ctors);
+#endif
 
 #ifdef CONFIG_MARKERS
        mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers",
@@ -2184,7 +2247,19 @@ static noinline struct module *load_module(void __user *umod,
                                        sizeof(*mod->tracepoints),
                                        &mod->num_tracepoints);
 #endif
-
+#ifdef CONFIG_EVENT_TRACING
+       mod->trace_events = section_objs(hdr, sechdrs, secstrings,
+                                        "_ftrace_events",
+                                        sizeof(*mod->trace_events),
+                                        &mod->num_trace_events);
+#endif
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+       /* sechdrs[0].sh_size is always zero */
+       mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings,
+                                            "__mcount_loc",
+                                            sizeof(*mod->ftrace_callsites),
+                                            &mod->num_ftrace_callsites);
+#endif
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !mod->crcs)
            || (mod->num_gpl_syms && !mod->gpl_crcs)
@@ -2249,11 +2324,6 @@ static noinline struct module *load_module(void __user *umod,
                        dynamic_debug_setup(debug, num_debug);
        }
 
-       /* sechdrs[0].sh_size is always zero */
-       mseg = section_objs(hdr, sechdrs, secstrings, "__mcount_loc",
-                           sizeof(*mseg), &num_mcount);
-       ftrace_init_module(mod, mseg, mseg + num_mcount);
-
        err = module_finalize(hdr, sechdrs, mod);
        if (err < 0)
                goto cleanup;
@@ -2303,17 +2373,19 @@ static noinline struct module *load_module(void __user *umod,
        /* Get rid of temporary copy */
        vfree(hdr);
 
-       stop_machine_destroy();
+       trace_module_load(mod);
+
        /* Done! */
        return mod;
 
  unlink:
-       stop_machine(__unlink_module, mod, NULL);
+       /* Unlink carefully: kallsyms could be walking list. */
+       list_del_rcu(&mod->list);
+       synchronize_sched();
        module_arch_cleanup(mod);
  cleanup:
        kobject_del(&mod->mkobj.kobj);
        kobject_put(&mod->mkobj.kobj);
-       ftrace_release(mod->module_core, mod->core_size);
  free_unload:
        module_unload_free(mod);
 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
@@ -2331,7 +2403,6 @@ static noinline struct module *load_module(void __user *umod,
        kfree(args);
  free_hdr:
        vfree(hdr);
-       stop_machine_destroy();
        return ERR_PTR(err);
 
  truncated:
@@ -2340,6 +2411,17 @@ static noinline struct module *load_module(void __user *umod,
        goto free_hdr;
 }
 
+/* Call module constructors. */
+static void do_mod_ctors(struct module *mod)
+{
+#ifdef CONFIG_CONSTRUCTORS
+       unsigned long i;
+
+       for (i = 0; i < mod->num_ctors; i++)
+               mod->ctors[i]();
+#endif
+}
+
 /* This is where the real work happens */
 SYSCALL_DEFINE3(init_module, void __user *, umod,
                unsigned long, len, const char __user *, uargs)
@@ -2348,7 +2430,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        int ret = 0;
 
        /* Must have permission */
-       if (!capable(CAP_SYS_MODULE))
+       if (!capable(CAP_SYS_MODULE) || modules_disabled)
                return -EPERM;
 
        /* Only one module load at a time, please */
@@ -2368,6 +2450,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        blocking_notifier_call_chain(&module_notify_list,
                        MODULE_STATE_COMING, mod);
 
+       do_mod_ctors(mod);
        /* Start the module */
        if (mod->init != NULL)
                ret = do_one_initcall(mod->init);
@@ -2386,9 +2469,9 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
                return ret;
        }
        if (ret > 0) {
-               printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, "
-                                   "it should follow 0/-E convention\n"
-                      KERN_WARNING "%s: loading module anyway...\n",
+               printk(KERN_WARNING
+"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n"
+"%s: loading module anyway...\n",
                       __func__, mod->name, ret,
                       __func__);
                dump_stack();
@@ -2400,9 +2483,13 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
        blocking_notifier_call_chain(&module_notify_list,
                                     MODULE_STATE_LIVE, mod);
 
+       /* We need to finish all async code before the module init sequence is done */
+       async_synchronize_full();
+
        mutex_lock(&module_mutex);
        /* Drop initial reference. */
        module_put(mod);
+       trim_init_extable(mod);
        module_free(mod, mod->module_init);
        mod->module_init = NULL;
        mod->init_size = 0;
@@ -2786,7 +2873,7 @@ bool is_module_address(unsigned long addr)
  * Must be called with preempt disabled or module mutex held so that
  * module doesn't get freed during this.
  */
-__notrace_funcgraph struct module *__module_address(unsigned long addr)
+struct module *__module_address(unsigned long addr)
 {
        struct module *mod;
 
@@ -2846,7 +2933,7 @@ void print_modules(void)
        struct module *mod;
        char buf[8];
 
-       printk("Modules linked in:");
+       printk(KERN_DEFAULT "Modules linked in:");
        /* Most callers should already have preempt disabled, but make sure */
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list)
@@ -2858,9 +2945,17 @@ void print_modules(void)
 }
 
 #ifdef CONFIG_MODVERSIONS
-/* Generate the signature for struct module here, too, for modversions. */
-void struct_module(struct module *mod) { return; }
-EXPORT_SYMBOL(struct_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,
+                  struct kernel_symbol *ks,
+                  struct marker *marker,
+                  struct tracepoint *tp)
+{
+}
+EXPORT_SYMBOL(module_layout);
 #endif
 
 #ifdef CONFIG_MARKERS