diff options
-rw-r--r-- | CREDITS | 3 | ||||
-rw-r--r-- | include/linux/module.h | 4 | ||||
-rw-r--r-- | kernel/module.c | 26 |
3 files changed, 24 insertions, 9 deletions
@@ -2478,7 +2478,8 @@ S: Derbyshire DE4 3RL | |||
2478 | S: United Kingdom | 2478 | S: United Kingdom |
2479 | 2479 | ||
2480 | N: Ian S. Nelson | 2480 | N: Ian S. Nelson |
2481 | E: ian.nelson@echostar.com | 2481 | E: nelsonis@earthlink.net |
2482 | P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6 9E97 576F 1B97 00D3 D983 | ||
2482 | D: Minor mmap and ide hacks | 2483 | D: Minor mmap and ide hacks |
2483 | S: 1370 Atlantis Ave. | 2484 | S: 1370 Atlantis Ave. |
2484 | S: Lafayette CO, 80026 | 2485 | S: Lafayette CO, 80026 |
diff --git a/include/linux/module.h b/include/linux/module.h index d4486cc2e7fe..2c599175c583 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -232,17 +232,17 @@ enum module_state | |||
232 | }; | 232 | }; |
233 | 233 | ||
234 | /* Similar stuff for section attributes. */ | 234 | /* Similar stuff for section attributes. */ |
235 | #define MODULE_SECT_NAME_LEN 32 | ||
236 | struct module_sect_attr | 235 | struct module_sect_attr |
237 | { | 236 | { |
238 | struct module_attribute mattr; | 237 | struct module_attribute mattr; |
239 | char name[MODULE_SECT_NAME_LEN]; | 238 | char *name; |
240 | unsigned long address; | 239 | unsigned long address; |
241 | }; | 240 | }; |
242 | 241 | ||
243 | struct module_sect_attrs | 242 | struct module_sect_attrs |
244 | { | 243 | { |
245 | struct attribute_group grp; | 244 | struct attribute_group grp; |
245 | int nsections; | ||
246 | struct module_sect_attr attrs[0]; | 246 | struct module_sect_attr attrs[0]; |
247 | }; | 247 | }; |
248 | 248 | ||
diff --git a/kernel/module.c b/kernel/module.c index b7fe6e840963..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 | { |