kprobes: rename kprobe_enabled to kprobes_all_disarmed
[safe/jmp/linux-2.6] / kernel / module.c
index bd15a94..05f014e 100644 (file)
@@ -68,7 +68,8 @@
 
 /* List of modules, protected by module_mutex or preempt_disable
  * (delete uses stop_machine/add uses RCU list operations). */
-static DEFINE_MUTEX(module_mutex);
+DEFINE_MUTEX(module_mutex);
+EXPORT_SYMBOL_GPL(module_mutex);
 static LIST_HEAD(modules);
 
 /* Waiting for a module to finish initializing? */
@@ -186,17 +187,6 @@ extern const unsigned long __start___kcrctab_unused_gpl[];
 #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
-struct symsearch {
-       const struct kernel_symbol *start, *stop;
-       const unsigned long *crcs;
-       enum {
-               NOT_GPL_ONLY,
-               GPL_ONLY,
-               WILL_BE_GPL_ONLY,
-       } licence;
-       bool unused;
-};
-
 static bool each_symbol_in_section(const struct symsearch *arr,
                                   unsigned int arrsize,
                                   struct module *owner,
@@ -217,10 +207,8 @@ static bool each_symbol_in_section(const struct symsearch *arr,
 }
 
 /* Returns true as soon as fn returns true, otherwise false. */
-static bool each_symbol(bool (*fn)(const struct symsearch *arr,
-                                  struct module *owner,
-                                  unsigned int symnum, void *data),
-                       void *data)
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+                           unsigned int symnum, void *data), void *data)
 {
        struct module *mod;
        const struct symsearch arr[] = {
@@ -273,6 +261,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr,
        }
        return false;
 }
+EXPORT_SYMBOL_GPL(each_symbol);
 
 struct find_symbol_arg {
        /* Input */
@@ -330,11 +319,11 @@ static bool find_symbol_in_section(const struct symsearch *syms,
 
 /* Find a symbol and return it, along with, (optional) crc and
  * (optional) module which owns it */
-static const struct kernel_symbol *find_symbol(const char *name,
-                                              struct module **owner,
-                                              const unsigned long **crc,
-                                              bool gplok,
-                                              bool warn)
+const struct kernel_symbol *find_symbol(const char *name,
+                                       struct module **owner,
+                                       const unsigned long **crc,
+                                       bool gplok,
+                                       bool warn)
 {
        struct find_symbol_arg fsa;
 
@@ -353,9 +342,10 @@ static const struct kernel_symbol *find_symbol(const char *name,
        DEBUGP("Failed to find symbol %s\n", name);
        return NULL;
 }
+EXPORT_SYMBOL_GPL(find_symbol);
 
 /* Search for module by name: must hold module_mutex. */
-static struct module *find_module(const char *name)
+struct module *find_module(const char *name)
 {
        struct module *mod;
 
@@ -365,6 +355,7 @@ static struct module *find_module(const char *name)
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(find_module);
 
 #ifdef CONFIG_SMP
 
@@ -641,7 +632,7 @@ static int already_uses(struct module *a, struct module *b)
 }
 
 /* Module a uses b */
-static int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
 {
        struct module_use *use;
        int no_warn, err;
@@ -674,6 +665,7 @@ static int use_module(struct module *a, struct module *b)
        no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
        return 1;
 }
+EXPORT_SYMBOL_GPL(use_module);
 
 /* Clear the unload stuff of the module. */
 static void module_unload_free(struct module *mod)
@@ -908,8 +900,10 @@ void symbol_put_addr(void *addr)
        if (core_kernel_text((unsigned long)addr))
                return;
 
-       if (!(modaddr = module_text_address((unsigned long)addr)))
-               BUG();
+       /* 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);
+       BUG_ON(!modaddr);
        module_put(modaddr);
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
@@ -949,10 +943,11 @@ static inline void module_unload_free(struct module *mod)
 {
 }
 
-static inline int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
 {
        return strong_try_module_get(b) == 0;
 }
+EXPORT_SYMBOL_GPL(use_module);
 
 static inline void module_unload_init(struct module *mod)
 {
@@ -995,12 +990,12 @@ static struct module_attribute *modinfo_attrs[] = {
 
 static const char vermagic[] = VERMAGIC_STRING;
 
-static int try_to_force_load(struct module *mod, const char *symname)
+static int try_to_force_load(struct module *mod, const char *reason)
 {
 #ifdef CONFIG_MODULE_FORCE_LOAD
        if (!test_taint(TAINT_FORCED_MODULE))
-               printk("%s: no version for \"%s\" found: kernel tainted.\n",
-                      mod->name, symname);
+               printk(KERN_WARNING "%s: %s: kernel tainted.\n",
+                      mod->name, reason);
        add_taint_module(mod, TAINT_FORCED_MODULE);
        return 0;
 #else
@@ -1057,9 +1052,9 @@ 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_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. */
@@ -1678,8 +1673,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);
@@ -1696,8 +1690,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);
@@ -1830,8 +1823,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 '?';
 }
@@ -1917,12 +1909,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;
@@ -1963,7 +1949,7 @@ 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
        }
@@ -2007,7 +1993,7 @@ static noinline struct module *load_module(void __user *umod,
        modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
-               err = try_to_force_load(mod, "magic");
+               err = try_to_force_load(mod, "bad vermagic");
                if (err)
                        goto free_hdr;
        } else if (!same_magic(modmagic, vermagic, versindex)) {
@@ -2196,8 +2182,8 @@ static noinline struct module *load_module(void __user *umod,
            || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
 #endif
                ) {
-               printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
-               err = try_to_force_load(mod, "nocrc");
+               err = try_to_force_load(mod,
+                                       "no versions for exported symbols");
                if (err)
                        goto cleanup;
        }
@@ -2305,12 +2291,13 @@ static noinline struct module *load_module(void __user *umod,
        /* Get rid of temporary copy */
        vfree(hdr);
 
-       stop_machine_destroy();
        /* 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);
@@ -2333,7 +2320,6 @@ static noinline struct module *load_module(void __user *umod,
        kfree(args);
  free_hdr:
        vfree(hdr);
-       stop_machine_destroy();
        return ERR_PTR(err);
 
  truncated:
@@ -2610,6 +2596,25 @@ unsigned long module_kallsyms_lookup_name(const char *name)
        preempt_enable();
        return ret;
 }
+
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+                                            struct module *, unsigned long),
+                                  void *data)
+{
+       struct module *mod;
+       unsigned int i;
+       int ret;
+
+       list_for_each_entry(mod, &modules, list) {
+               for (i = 0; i < mod->num_symtab; i++) {
+                       ret = fn(data, mod->strtab + mod->symtab[i].st_name,
+                                mod, mod->symtab[i].st_value);
+                       if (ret != 0)
+                               return ret;
+               }
+       }
+       return 0;
+}
 #endif /* CONFIG_KALLSYMS */
 
 static char *module_flags(struct module *mod, char *buf)
@@ -2769,7 +2774,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;
 
@@ -2782,6 +2787,7 @@ __notrace_funcgraph struct module *__module_address(unsigned long addr)
                        return mod;
        return NULL;
 }
+EXPORT_SYMBOL_GPL(__module_address);
 
 /*
  * is_module_text_address - is this address inside module code?
@@ -2820,17 +2826,7 @@ struct module *__module_text_address(unsigned long addr)
        }
        return mod;
 }
-
-struct module *module_text_address(unsigned long addr)
-{
-       struct module *mod;
-
-       preempt_disable();
-       mod = __module_text_address(addr);
-       preempt_enable();
-
-       return mod;
-}
+EXPORT_SYMBOL_GPL(__module_text_address);
 
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
@@ -2850,9 +2846,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