diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 32 | 
1 files changed, 26 insertions, 6 deletions
| diff --git a/kernel/module.c b/kernel/module.c index 2a19cd47c046..05625d5dc758 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -933,6 +933,15 @@ static ssize_t module_sect_show(struct module_attribute *mattr, | |||
| 933 | return sprintf(buf, "0x%lx\n", sattr->address); | 933 | return sprintf(buf, "0x%lx\n", sattr->address); | 
| 934 | } | 934 | } | 
| 935 | 935 | ||
| 936 | static void free_sect_attrs(struct module_sect_attrs *sect_attrs) | ||
| 937 | { | ||
| 938 | int section; | ||
| 939 | |||
| 940 | for (section = 0; section < sect_attrs->nsections; section++) | ||
| 941 | kfree(sect_attrs->attrs[section].name); | ||
| 942 | kfree(sect_attrs); | ||
| 943 | } | ||
| 944 | |||
| 936 | static void add_sect_attrs(struct module *mod, unsigned int nsect, | 945 | static void add_sect_attrs(struct module *mod, unsigned int nsect, | 
| 937 | char *secstrings, Elf_Shdr *sechdrs) | 946 | char *secstrings, Elf_Shdr *sechdrs) | 
| 938 | { | 947 | { | 
| @@ -949,21 +958,26 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
| 949 | + nloaded * sizeof(sect_attrs->attrs[0]), | 958 | + nloaded * sizeof(sect_attrs->attrs[0]), | 
| 950 | sizeof(sect_attrs->grp.attrs[0])); | 959 | sizeof(sect_attrs->grp.attrs[0])); | 
| 951 | size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); | 960 | size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); | 
| 952 | if (! (sect_attrs = kmalloc(size[0] + size[1], GFP_KERNEL))) | 961 | sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL); | 
| 962 | if (sect_attrs == NULL) | ||
| 953 | return; | 963 | return; | 
| 954 | 964 | ||
| 955 | /* Setup section attributes. */ | 965 | /* Setup section attributes. */ | 
| 956 | sect_attrs->grp.name = "sections"; | 966 | sect_attrs->grp.name = "sections"; | 
| 957 | sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; | 967 | sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; | 
| 958 | 968 | ||
| 969 | sect_attrs->nsections = 0; | ||
| 959 | sattr = §_attrs->attrs[0]; | 970 | sattr = §_attrs->attrs[0]; | 
| 960 | gattr = §_attrs->grp.attrs[0]; | 971 | gattr = §_attrs->grp.attrs[0]; | 
| 961 | for (i = 0; i < nsect; i++) { | 972 | for (i = 0; i < nsect; i++) { | 
| 962 | if (! (sechdrs[i].sh_flags & SHF_ALLOC)) | 973 | if (! (sechdrs[i].sh_flags & SHF_ALLOC)) | 
| 963 | continue; | 974 | continue; | 
| 964 | sattr->address = sechdrs[i].sh_addr; | 975 | sattr->address = sechdrs[i].sh_addr; | 
| 965 | strlcpy(sattr->name, secstrings + sechdrs[i].sh_name, | 976 | sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, | 
| 966 | MODULE_SECT_NAME_LEN); | 977 | GFP_KERNEL); | 
| 978 | if (sattr->name == NULL) | ||
| 979 | goto out; | ||
| 980 | sect_attrs->nsections++; | ||
| 967 | sattr->mattr.show = module_sect_show; | 981 | sattr->mattr.show = module_sect_show; | 
| 968 | sattr->mattr.store = NULL; | 982 | sattr->mattr.store = NULL; | 
| 969 | sattr->mattr.attr.name = sattr->name; | 983 | sattr->mattr.attr.name = sattr->name; | 
| @@ -979,7 +993,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
| 979 | mod->sect_attrs = sect_attrs; | 993 | mod->sect_attrs = sect_attrs; | 
| 980 | return; | 994 | return; | 
| 981 | out: | 995 | out: | 
| 982 | kfree(sect_attrs); | 996 | free_sect_attrs(sect_attrs); | 
| 983 | } | 997 | } | 
| 984 | 998 | ||
| 985 | static void remove_sect_attrs(struct module *mod) | 999 | static void remove_sect_attrs(struct module *mod) | 
| @@ -989,13 +1003,13 @@ static void remove_sect_attrs(struct module *mod) | |||
| 989 | &mod->sect_attrs->grp); | 1003 | &mod->sect_attrs->grp); | 
| 990 | /* We are positive that no one is using any sect attrs | 1004 | /* We are positive that no one is using any sect attrs | 
| 991 | * at this point. Deallocate immediately. */ | 1005 | * at this point. Deallocate immediately. */ | 
| 992 | kfree(mod->sect_attrs); | 1006 | free_sect_attrs(mod->sect_attrs); | 
| 993 | mod->sect_attrs = NULL; | 1007 | mod->sect_attrs = NULL; | 
| 994 | } | 1008 | } | 
| 995 | } | 1009 | } | 
| 996 | 1010 | ||
| 997 | |||
| 998 | #else | 1011 | #else | 
| 1012 | |||
| 999 | static inline void add_sect_attrs(struct module *mod, unsigned int nsect, | 1013 | static inline void add_sect_attrs(struct module *mod, unsigned int nsect, | 
| 1000 | char *sectstrings, Elf_Shdr *sechdrs) | 1014 | char *sectstrings, Elf_Shdr *sechdrs) | 
| 1001 | { | 1015 | { | 
| @@ -1054,6 +1068,12 @@ static int mod_sysfs_setup(struct module *mod, | |||
| 1054 | { | 1068 | { | 
| 1055 | int err; | 1069 | int err; | 
| 1056 | 1070 | ||
| 1071 | if (!module_subsys.kset.subsys) { | ||
| 1072 | printk(KERN_ERR "%s: module_subsys not initialized\n", | ||
| 1073 | mod->name); | ||
| 1074 | err = -EINVAL; | ||
| 1075 | goto out; | ||
| 1076 | } | ||
| 1057 | memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); | 1077 | memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); | 
| 1058 | err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name); | 1078 | err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name); | 
| 1059 | if (err) | 1079 | if (err) | 
