Commit 6526c534b2677ca601b7b92851437feb041d02a1
1 parent
49668688dd
Exists in
master
and in
20 other branches
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>
Showing 1 changed file with 13 additions and 15 deletions Side-by-side Diff
kernel/module.c
... | ... | @@ -114,7 +114,7 @@ |
114 | 114 | Elf_Ehdr *hdr; |
115 | 115 | unsigned long len; |
116 | 116 | Elf_Shdr *sechdrs; |
117 | - char *secstrings, *args, *strtab; | |
117 | + char *secstrings, *strtab; | |
118 | 118 | unsigned long *strmap; |
119 | 119 | unsigned long symoffs, stroffs; |
120 | 120 | struct { |
... | ... | @@ -2096,7 +2096,7 @@ |
2096 | 2096 | } |
2097 | 2097 | #endif |
2098 | 2098 | |
2099 | -/* Sets info->hdr, info->len and info->args. */ | |
2099 | +/* Sets info->hdr and info->len. */ | |
2100 | 2100 | static int copy_and_check(struct load_info *info, |
2101 | 2101 | const void __user *umod, unsigned long len, |
2102 | 2102 | const char __user *uargs) |
... | ... | @@ -2132,13 +2132,6 @@ |
2132 | 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 | 2135 | info->hdr = hdr; |
2143 | 2136 | info->len = len; |
2144 | 2137 | return 0; |
... | ... | @@ -2150,7 +2143,6 @@ |
2150 | 2143 | |
2151 | 2144 | static void free_copy(struct load_info *info) |
2152 | 2145 | { |
2153 | - kfree(info->args); | |
2154 | 2146 | vfree(info->hdr); |
2155 | 2147 | } |
2156 | 2148 | |
... | ... | @@ -2468,7 +2460,7 @@ |
2468 | 2460 | err = module_frob_arch_sections(info->hdr, info->sechdrs, |
2469 | 2461 | info->secstrings, mod); |
2470 | 2462 | if (err < 0) |
2471 | - goto free_args; | |
2463 | + goto out; | |
2472 | 2464 | |
2473 | 2465 | pcpusec = &info->sechdrs[info->index.pcpu]; |
2474 | 2466 | if (pcpusec->sh_size) { |
... | ... | @@ -2476,7 +2468,7 @@ |
2476 | 2468 | err = percpu_modalloc(mod, |
2477 | 2469 | pcpusec->sh_size, pcpusec->sh_addralign); |
2478 | 2470 | if (err) |
2479 | - goto free_args; | |
2471 | + goto out; | |
2480 | 2472 | pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC; |
2481 | 2473 | } |
2482 | 2474 | |
... | ... | @@ -2507,8 +2499,7 @@ |
2507 | 2499 | kfree(info->strmap); |
2508 | 2500 | free_percpu: |
2509 | 2501 | percpu_modfree(mod); |
2510 | -free_args: | |
2511 | - kfree(info->args); | |
2502 | +out: | |
2512 | 2503 | return ERR_PTR(err); |
2513 | 2504 | } |
2514 | 2505 | |
... | ... | @@ -2594,7 +2585,12 @@ |
2594 | 2585 | |
2595 | 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 | 2595 | mod->state = MODULE_STATE_COMING; |
2600 | 2596 | |
... | ... | @@ -2648,6 +2644,8 @@ |
2648 | 2644 | unlock: |
2649 | 2645 | mutex_unlock(&module_mutex); |
2650 | 2646 | synchronize_sched(); |
2647 | + kfree(mod->args); | |
2648 | + free_arch_cleanup: | |
2651 | 2649 | module_arch_cleanup(mod); |
2652 | 2650 | free_modinfo: |
2653 | 2651 | free_modinfo(mod); |