aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/module.c28
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. */
2100static int copy_and_check(struct load_info *info, 2100static 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
2151static void free_copy(struct load_info *info) 2144static 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);
2508free_percpu: 2500free_percpu:
2509 percpu_modfree(mod); 2501 percpu_modfree(mod);
2510free_args: 2502out:
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);