]> err.no Git - linux-2.6/blobdiff - kernel/module.c
NTP: correct inconsistent ntp interval/tick_length usage
[linux-2.6] / kernel / module.c
index 12067ff34d01c242e637bddf460d65328c293a63..f6a4e721fd4907339dfbbca63d5081244697973f 100644 (file)
@@ -1230,6 +1230,7 @@ void module_remove_modinfo_attrs(struct module *mod)
 int mod_sysfs_init(struct module *mod)
 {
        int err;
+       struct kobject *kobj;
 
        if (!module_sysfs_initialized) {
                printk(KERN_ERR "%s: module sysfs not initialized\n",
@@ -1237,6 +1238,15 @@ int mod_sysfs_init(struct module *mod)
                err = -EINVAL;
                goto out;
        }
+
+       kobj = kset_find_obj(module_kset, mod->name);
+       if (kobj) {
+               printk(KERN_ERR "%s: module is already loaded\n", mod->name);
+               kobject_put(kobj);
+               err = -EINVAL;
+               goto out;
+       }
+
        mod->mkobj.mod = mod;
 
        memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
@@ -1916,7 +1926,7 @@ static struct module *load_module(void __user *umod,
        set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
        if (strcmp(mod->name, "ndiswrapper") == 0)
-               add_taint(TAINT_PROPRIETARY_MODULE);
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
        if (strcmp(mod->name, "driverloader") == 0)
                add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 
@@ -2230,14 +2240,13 @@ static const char *get_ksymbol(struct module *mod,
        return mod->strtab + mod->symtab[best].st_name;
 }
 
-/* For kallsyms to ask for address resolution.  NULL means not found.
-   We don't lock, as this is used for oops resolution and races are a
-   lesser concern. */
-/* FIXME: Risky: returns a pointer into a module w/o lock */
-const char *module_address_lookup(unsigned long addr,
-                                 unsigned long *size,
-                                 unsigned long *offset,
-                                 char **modname)
+/* For kallsyms to ask for address resolution.  NULL means not found.  Careful
+ * not to lock to avoid deadlock on oopses, simply disable preemption. */
+char *module_address_lookup(unsigned long addr,
+                           unsigned long *size,
+                           unsigned long *offset,
+                           char **modname,
+                           char *namebuf)
 {
        struct module *mod;
        const char *ret = NULL;
@@ -2252,8 +2261,13 @@ const char *module_address_lookup(unsigned long addr,
                        break;
                }
        }
+       /* Make a copy in here where it's safe */
+       if (ret) {
+               strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
+               ret = namebuf;
+       }
        preempt_enable();
-       return ret;
+       return (char *)ret;
 }
 
 int lookup_module_symbol_name(unsigned long addr, char *symname)