mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 22:02:02 +00:00
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>
This commit is contained in:
parent
49668688dd
commit
6526c534b2
1 changed files with 13 additions and 15 deletions
|
@ -114,7 +114,7 @@ struct load_info {
|
||||||
Elf_Ehdr *hdr;
|
Elf_Ehdr *hdr;
|
||||||
unsigned long len;
|
unsigned long len;
|
||||||
Elf_Shdr *sechdrs;
|
Elf_Shdr *sechdrs;
|
||||||
char *secstrings, *args, *strtab;
|
char *secstrings, *strtab;
|
||||||
unsigned long *strmap;
|
unsigned long *strmap;
|
||||||
unsigned long symoffs, stroffs;
|
unsigned long symoffs, stroffs;
|
||||||
struct {
|
struct {
|
||||||
|
@ -2096,7 +2096,7 @@ static inline void kmemleak_load_module(const struct module *mod,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Sets info->hdr, info->len and info->args. */
|
/* Sets info->hdr and info->len. */
|
||||||
static int copy_and_check(struct load_info *info,
|
static int copy_and_check(struct load_info *info,
|
||||||
const void __user *umod, unsigned long len,
|
const void __user *umod, unsigned long len,
|
||||||
const char __user *uargs)
|
const char __user *uargs)
|
||||||
|
@ -2132,13 +2132,6 @@ static int copy_and_check(struct load_info *info,
|
||||||
goto free_hdr;
|
goto free_hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now copy in args */
|
|
||||||
info->args = strndup_user(uargs, ~0UL >> 1);
|
|
||||||
if (IS_ERR(info->args)) {
|
|
||||||
err = PTR_ERR(info->args);
|
|
||||||
goto free_hdr;
|
|
||||||
}
|
|
||||||
|
|
||||||
info->hdr = hdr;
|
info->hdr = hdr;
|
||||||
info->len = len;
|
info->len = len;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2150,7 +2143,6 @@ static int copy_and_check(struct load_info *info,
|
||||||
|
|
||||||
static void free_copy(struct load_info *info)
|
static void free_copy(struct load_info *info)
|
||||||
{
|
{
|
||||||
kfree(info->args);
|
|
||||||
vfree(info->hdr);
|
vfree(info->hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2468,7 +2460,7 @@ static struct module *layout_and_allocate(struct load_info *info)
|
||||||
err = module_frob_arch_sections(info->hdr, info->sechdrs,
|
err = module_frob_arch_sections(info->hdr, info->sechdrs,
|
||||||
info->secstrings, mod);
|
info->secstrings, mod);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto free_args;
|
goto out;
|
||||||
|
|
||||||
pcpusec = &info->sechdrs[info->index.pcpu];
|
pcpusec = &info->sechdrs[info->index.pcpu];
|
||||||
if (pcpusec->sh_size) {
|
if (pcpusec->sh_size) {
|
||||||
|
@ -2476,7 +2468,7 @@ static struct module *layout_and_allocate(struct load_info *info)
|
||||||
err = percpu_modalloc(mod,
|
err = percpu_modalloc(mod,
|
||||||
pcpusec->sh_size, pcpusec->sh_addralign);
|
pcpusec->sh_size, pcpusec->sh_addralign);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_args;
|
goto out;
|
||||||
pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC;
|
pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2507,8 +2499,7 @@ static struct module *layout_and_allocate(struct load_info *info)
|
||||||
kfree(info->strmap);
|
kfree(info->strmap);
|
||||||
free_percpu:
|
free_percpu:
|
||||||
percpu_modfree(mod);
|
percpu_modfree(mod);
|
||||||
free_args:
|
out:
|
||||||
kfree(info->args);
|
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2594,7 +2585,12 @@ static noinline struct module *load_module(void __user *umod,
|
||||||
|
|
||||||
flush_module_icache(mod);
|
flush_module_icache(mod);
|
||||||
|
|
||||||
mod->args = info.args;
|
/* Now copy in args */
|
||||||
|
mod->args = strndup_user(uargs, ~0UL >> 1);
|
||||||
|
if (IS_ERR(mod->args)) {
|
||||||
|
err = PTR_ERR(mod->args);
|
||||||
|
goto free_arch_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
mod->state = MODULE_STATE_COMING;
|
mod->state = MODULE_STATE_COMING;
|
||||||
|
|
||||||
|
@ -2648,6 +2644,8 @@ static noinline struct module *load_module(void __user *umod,
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&module_mutex);
|
mutex_unlock(&module_mutex);
|
||||||
synchronize_sched();
|
synchronize_sched();
|
||||||
|
kfree(mod->args);
|
||||||
|
free_arch_cleanup:
|
||||||
module_arch_cleanup(mod);
|
module_arch_cleanup(mod);
|
||||||
free_modinfo:
|
free_modinfo:
|
||||||
free_modinfo(mod);
|
free_modinfo(mod);
|
||||||
|
|
Loading…
Reference in a new issue