]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - kernel/module.c
[PATCH] /sys/modules: allow full length section names
[net-next-2.6.git] / kernel / module.c
index 281172f01e9a032c6285ce6a43c2f8d97c42aa75..05625d5dc7583ac5567d3deec22ebd95c57b72bc 100644 (file)
@@ -933,6 +933,15 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
        return sprintf(buf, "0x%lx\n", sattr->address);
 }
 
+static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
+{
+       int section;
+
+       for (section = 0; section < sect_attrs->nsections; section++)
+               kfree(sect_attrs->attrs[section].name);
+       kfree(sect_attrs);
+}
+
 static void add_sect_attrs(struct module *mod, unsigned int nsect,
                char *secstrings, Elf_Shdr *sechdrs)
 {
@@ -949,21 +958,26 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
                        + nloaded * sizeof(sect_attrs->attrs[0]),
                        sizeof(sect_attrs->grp.attrs[0]));
        size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
-       if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL)))
+       sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
+       if (sect_attrs == NULL)
                return;
 
        /* Setup section attributes. */
        sect_attrs->grp.name = "sections";
        sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
 
+       sect_attrs->nsections = 0;
        sattr = &sect_attrs->attrs[0];
        gattr = &sect_attrs->grp.attrs[0];
        for (i = 0; i < nsect; i++) {
                if (! (sechdrs[i].sh_flags & SHF_ALLOC))
                        continue;
                sattr->address = sechdrs[i].sh_addr;
-               strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
-                       MODULE_SECT_NAME_LEN);
+               sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
+                                       GFP_KERNEL);
+               if (sattr->name == NULL)
+                       goto out;
+               sect_attrs->nsections++;
                sattr->mattr.show = module_sect_show;
                sattr->mattr.store = NULL;
                sattr->mattr.attr.name = sattr->name;
@@ -979,7 +993,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
        mod->sect_attrs = sect_attrs;
        return;
   out:
-       kfree(sect_attrs);
+       free_sect_attrs(sect_attrs);
 }
 
 static void remove_sect_attrs(struct module *mod)
@@ -989,13 +1003,13 @@ static void remove_sect_attrs(struct module *mod)
                                   &mod->sect_attrs->grp);
                /* We are positive that no one is using any sect attrs
                 * at this point.  Deallocate immediately. */
-               kfree(mod->sect_attrs);
+               free_sect_attrs(mod->sect_attrs);
                mod->sect_attrs = NULL;
        }
 }
 
-
 #else
+
 static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
                char *sectstrings, Elf_Shdr *sechdrs)
 {
@@ -1054,6 +1068,12 @@ static int mod_sysfs_setup(struct module *mod,
 {
        int err;
 
+       if (!module_subsys.kset.subsys) {
+               printk(KERN_ERR "%s: module_subsys not initialized\n",
+                      mod->name);
+               err = -EINVAL;
+               goto out;
+       }
        memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
        err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
        if (err)
@@ -1121,6 +1141,9 @@ static void free_module(struct module *mod)
        if (mod->percpu)
                percpu_modfree(mod->percpu);
 
+       /* Free lock-classes: */
+       lockdep_free_key_range(mod->module_core, mod->core_size);
+
        /* Finally, free the core (containing the module structure) */
        module_free(mod, mod->module_core);
 }
@@ -2016,10 +2039,8 @@ const char *module_address_lookup(unsigned long addr,
        return NULL;
 }
 
-struct module *module_get_kallsym(unsigned int symnum,
-                                 unsigned long *value,
-                                 char *type,
-                                 char namebuf[128])
+struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
+                               char *type, char *name, size_t namelen)
 {
        struct module *mod;
 
@@ -2028,9 +2049,8 @@ struct module *module_get_kallsym(unsigned int symnum,
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
                        *type = mod->symtab[symnum].st_info;
-                       strncpy(namebuf,
-                               mod->strtab + mod->symtab[symnum].st_name,
-                               127);
+                       strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
+                               namelen);
                        mutex_unlock(&module_mutex);
                        return mod;
                }
@@ -2159,6 +2179,29 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
        return e;
 }
 
+/*
+ * Is this a valid module address?
+ */
+int is_module_address(unsigned long addr)
+{
+       unsigned long flags;
+       struct module *mod;
+
+       spin_lock_irqsave(&modlist_lock, flags);
+
+       list_for_each_entry(mod, &modules, list) {
+               if (within(addr, mod->module_core, mod->core_size)) {
+                       spin_unlock_irqrestore(&modlist_lock, flags);
+                       return 1;
+               }
+       }
+
+       spin_unlock_irqrestore(&modlist_lock, flags);
+
+       return 0;
+}
+
+
 /* Is this a valid kernel address?  We don't grab the lock: we are oopsing. */
 struct module *__module_text_address(unsigned long addr)
 {