Commit 81a0abd9 authored by Jessica Yu's avatar Jessica Yu

module: make it clear when we're handling the module copy in info->hdr

In load_module(), it's not always clear whether we're handling the
temporary module copy in info->hdr (which is freed at the end of
load_module()) or if we're handling the module already allocated and
copied to it's final place. Adding an info->mod field and using it
whenever we're handling the temporary copy makes that explicitly clear.
Signed-off-by: default avatarJessica Yu <jeyu@kernel.org>
parent 9f2d1e68
...@@ -309,6 +309,8 @@ EXPORT_SYMBOL(unregister_module_notifier); ...@@ -309,6 +309,8 @@ EXPORT_SYMBOL(unregister_module_notifier);
struct load_info { struct load_info {
const char *name; const char *name;
/* pointer to module in temporary copy, freed at end of load_module() */
struct module *mod;
Elf_Ehdr *hdr; Elf_Ehdr *hdr;
unsigned long len; unsigned long len;
Elf_Shdr *sechdrs; Elf_Shdr *sechdrs;
...@@ -2947,14 +2949,13 @@ static int rewrite_section_headers(struct load_info *info, int flags) ...@@ -2947,14 +2949,13 @@ static int rewrite_section_headers(struct load_info *info, int flags)
* search for module section index etc), and do some basic section * search for module section index etc), and do some basic section
* verification. * verification.
* *
* Return the temporary module pointer (we'll replace it with the final * Set info->mod to the temporary copy of the module in info->hdr. The final one
* one when we move the module sections around). * will be allocated in move_module().
*/ */
static struct module *setup_load_info(struct load_info *info, int flags) static int setup_load_info(struct load_info *info, int flags)
{ {
unsigned int i; unsigned int i;
int err; int err;
struct module *mod;
/* Set up the convenience variables */ /* Set up the convenience variables */
info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
...@@ -2963,7 +2964,7 @@ static struct module *setup_load_info(struct load_info *info, int flags) ...@@ -2963,7 +2964,7 @@ static struct module *setup_load_info(struct load_info *info, int flags)
err = rewrite_section_headers(info, flags); err = rewrite_section_headers(info, flags);
if (err) if (err)
return ERR_PTR(err); return err;
/* Find internal symbols and strings. */ /* Find internal symbols and strings. */
for (i = 1; i < info->hdr->e_shnum; i++) { for (i = 1; i < info->hdr->e_shnum; i++) {
...@@ -2980,30 +2981,30 @@ static struct module *setup_load_info(struct load_info *info, int flags) ...@@ -2980,30 +2981,30 @@ static struct module *setup_load_info(struct load_info *info, int flags)
if (!info->index.mod) { if (!info->index.mod) {
pr_warn("%s: No module found in object\n", pr_warn("%s: No module found in object\n",
info->name ?: "(missing .modinfo name field)"); info->name ?: "(missing .modinfo name field)");
return ERR_PTR(-ENOEXEC); return -ENOEXEC;
} }
/* This is temporary: point mod into copy of data. */ /* This is temporary: point mod into copy of data. */
mod = (void *)info->sechdrs[info->index.mod].sh_addr; info->mod = (void *)info->sechdrs[info->index.mod].sh_addr;
/* /*
* If we didn't load the .modinfo 'name' field, fall back to * If we didn't load the .modinfo 'name' field, fall back to
* on-disk struct mod 'name' field. * on-disk struct mod 'name' field.
*/ */
if (!info->name) if (!info->name)
info->name = mod->name; info->name = info->mod->name;
if (info->index.sym == 0) { if (info->index.sym == 0) {
pr_warn("%s: module has no symbols (stripped?)\n", info->name); pr_warn("%s: module has no symbols (stripped?)\n", info->name);
return ERR_PTR(-ENOEXEC); return -ENOEXEC;
} }
info->index.pcpu = find_pcpusec(info); info->index.pcpu = find_pcpusec(info);
/* Check module struct version now, before we try to use module. */ /* Check module struct version now, before we try to use module. */
if (!check_modstruct_version(info, mod)) if (!check_modstruct_version(info, info->mod))
return ERR_PTR(-ENOEXEC); return -ENOEXEC;
return mod; return 0;
} }
static int check_modinfo(struct module *mod, struct load_info *info, int flags) static int check_modinfo(struct module *mod, struct load_info *info, int flags)
...@@ -3298,25 +3299,24 @@ core_param(module_blacklist, module_blacklist, charp, 0400); ...@@ -3298,25 +3299,24 @@ core_param(module_blacklist, module_blacklist, charp, 0400);
static struct module *layout_and_allocate(struct load_info *info, int flags) static struct module *layout_and_allocate(struct load_info *info, int flags)
{ {
/* Module within temporary copy. */
struct module *mod; struct module *mod;
unsigned int ndx; unsigned int ndx;
int err; int err;
mod = setup_load_info(info, flags); err = setup_load_info(info, flags);
if (IS_ERR(mod)) if (err)
return mod; return ERR_PTR(err);
if (blacklisted(info->name)) if (blacklisted(info->name))
return ERR_PTR(-EPERM); return ERR_PTR(-EPERM);
err = check_modinfo(mod, info, flags); err = check_modinfo(info->mod, info, flags);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
/* Allow arches to frob section contents and sizes. */ /* Allow arches to frob section contents and sizes. */
err = module_frob_arch_sections(info->hdr, info->sechdrs, err = module_frob_arch_sections(info->hdr, info->sechdrs,
info->secstrings, mod); info->secstrings, info->mod);
if (err < 0) if (err < 0)
return ERR_PTR(err); return ERR_PTR(err);
...@@ -3335,11 +3335,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) ...@@ -3335,11 +3335,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
/* Determine total sizes, and put offsets in sh_entsize. For now /* Determine total sizes, and put offsets in sh_entsize. For now
this is done generically; there doesn't appear to be any this is done generically; there doesn't appear to be any
special cases for the architectures. */ special cases for the architectures. */
layout_sections(mod, info); layout_sections(info->mod, info);
layout_symtab(mod, info); layout_symtab(info->mod, info);
/* Allocate and move to the final place */ /* Allocate and move to the final place */
err = move_module(mod, info); err = move_module(info->mod, info);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment