diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-05 14:59:10 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-04 23:29:12 -0400 |
commit | 6526c534b2677ca601b7b92851437feb041d02a1 (patch) | |
tree | d6d0f6d8cf2b685b2d1d345d938ca5816860dd89 /kernel/module.c | |
parent | 49668688dd5a5f46c72f965835388ed16c596055 (diff) |
module: move module args strndup_user to just before use
Instead of copying and allocating the args and storing it in
load_info, we can just allocate them right before we need them.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/kernel/module.c b/kernel/module.c index 29dd232f8183..cabafe228444 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -114,7 +114,7 @@ struct load_info { | |||
114 | Elf_Ehdr *hdr; | 114 | Elf_Ehdr *hdr; |
115 | unsigned long len; | 115 | unsigned long len; |
116 | Elf_Shdr *sechdrs; | 116 | Elf_Shdr *sechdrs; |
117 | char *secstrings, *args, *strtab; | 117 | char *secstrings, *strtab; |
118 | unsigned long *strmap; | 118 | unsigned long *strmap; |
119 | unsigned long symoffs, stroffs; | 119 | unsigned long symoffs, stroffs; |
120 | struct { | 120 | struct { |
@@ -2096,7 +2096,7 @@ static inline void kmemleak_load_module(const struct module *mod, | |||
2096 | } | 2096 | } |
2097 | #endif | 2097 | #endif |
2098 | 2098 | ||
2099 | /* Sets info->hdr, info->len and info->args. */ | 2099 | /* Sets info->hdr and info->len. */ |
2100 | static int copy_and_check(struct load_info *info, | 2100 | static int copy_and_check(struct load_info *info, |
2101 | const void __user *umod, unsigned long len, | 2101 | const void __user *umod, unsigned long len, |
2102 | const char __user *uargs) | 2102 | const char __user *uargs) |
@@ -2132,13 +2132,6 @@ static int copy_and_check(struct load_info *info, | |||
2132 | goto free_hdr; | 2132 | goto free_hdr; |
2133 | } | 2133 | } |
2134 | 2134 | ||
2135 | /* Now copy in args */ | ||
2136 | info->args = strndup_user(uargs, ~0UL >> 1); | ||
2137 | if (IS_ERR(info->args)) { | ||
2138 | err = PTR_ERR(info->args); | ||
2139 | goto free_hdr; | ||
2140 | } | ||
2141 | |||
2142 | info->hdr = hdr; | 2135 | info->hdr = hdr; |
2143 | info->len = len; | 2136 | info->len = len; |
2144 | return 0; | 2137 | return 0; |
@@ -2150,7 +2143,6 @@ free_hdr: | |||
2150 | 2143 | ||
2151 | static void free_copy(struct load_info *info) | 2144 | static void free_copy(struct load_info *info) |
2152 | { | 2145 | { |
2153 | kfree(info->args); | ||
2154 | vfree(info->hdr); | 2146 | vfree(info->hdr); |
2155 | } | 2147 | } |
2156 | 2148 | ||
@@ -2468,7 +2460,7 @@ static struct module *layout_and_allocate(struct load_info *info) | |||
2468 | err = module_frob_arch_sections(info->hdr, info->sechdrs, | 2460 | err = module_frob_arch_sections(info->hdr, info->sechdrs, |
2469 | info->secstrings, mod); | 2461 | info->secstrings, mod); |
2470 | if (err < 0) | 2462 | if (err < 0) |
2471 | goto free_args; | 2463 | goto out; |
2472 | 2464 | ||
2473 | pcpusec = &info->sechdrs[info->index.pcpu]; | 2465 | pcpusec = &info->sechdrs[info->index.pcpu]; |
2474 | if (pcpusec->sh_size) { | 2466 | if (pcpusec->sh_size) { |
@@ -2476,7 +2468,7 @@ static struct module *layout_and_allocate(struct load_info *info) | |||
2476 | err = percpu_modalloc(mod, | 2468 | err = percpu_modalloc(mod, |
2477 | pcpusec->sh_size, pcpusec->sh_addralign); | 2469 | pcpusec->sh_size, pcpusec->sh_addralign); |
2478 | if (err) | 2470 | if (err) |
2479 | goto free_args; | 2471 | goto out; |
2480 | pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC; | 2472 | pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC; |
2481 | } | 2473 | } |
2482 | 2474 | ||
@@ -2507,8 +2499,7 @@ free_strmap: | |||
2507 | kfree(info->strmap); | 2499 | kfree(info->strmap); |
2508 | free_percpu: | 2500 | free_percpu: |
2509 | percpu_modfree(mod); | 2501 | percpu_modfree(mod); |
2510 | free_args: | 2502 | out: |
2511 | kfree(info->args); | ||
2512 | return ERR_PTR(err); | 2503 | return ERR_PTR(err); |
2513 | } | 2504 | } |
2514 | 2505 | ||
@@ -2594,7 +2585,12 @@ static noinline struct module *load_module(void __user *umod, | |||
2594 | 2585 | ||
2595 | flush_module_icache(mod); | 2586 | flush_module_icache(mod); |
2596 | 2587 | ||
2597 | mod->args = info.args; | 2588 | /* Now copy in args */ |
2589 | mod->args = strndup_user(uargs, ~0UL >> 1); | ||
2590 | if (IS_ERR(mod->args)) { | ||
2591 | err = PTR_ERR(mod->args); | ||
2592 | goto free_arch_cleanup; | ||
2593 | } | ||
2598 | 2594 | ||
2599 | mod->state = MODULE_STATE_COMING; | 2595 | mod->state = MODULE_STATE_COMING; |
2600 | 2596 | ||
@@ -2648,6 +2644,8 @@ static noinline struct module *load_module(void __user *umod, | |||
2648 | unlock: | 2644 | unlock: |
2649 | mutex_unlock(&module_mutex); | 2645 | mutex_unlock(&module_mutex); |
2650 | synchronize_sched(); | 2646 | synchronize_sched(); |
2647 | kfree(mod->args); | ||
2648 | free_arch_cleanup: | ||
2651 | module_arch_cleanup(mod); | 2649 | module_arch_cleanup(mod); |
2652 | free_modinfo: | 2650 | free_modinfo: |
2653 | free_modinfo(mod); | 2651 | free_modinfo(mod); |