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 | |
| 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>
| -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); |
