Commit 41872921 authored by Rusty Russell's avatar Rusty Russell Committed by Linus Torvalds

[PATCH] Module length calculation fix and module with no init fix

Fixes miscalculation of required module size due to alignment issues of
first section after common, and also doesn't think that no init section
is an allocation failure.
parent 5c0f111c
...@@ -592,14 +592,17 @@ static void *copy_section(const char *name, ...@@ -592,14 +592,17 @@ static void *copy_section(const char *name,
{ {
void *dest; void *dest;
unsigned long *use; unsigned long *use;
unsigned long max;
/* Only copy to init section if there is one */ /* Only copy to init section if there is one */
if (strstr(name, ".init") && mod->module_init) { if (strstr(name, ".init") && mod->module_init) {
dest = mod->module_init; dest = mod->module_init;
use = &used->init_size; use = &used->init_size;
max = mod->init_size;
} else { } else {
dest = mod->module_core; dest = mod->module_core;
use = &used->core_size; use = &used->core_size;
max = mod->core_size;
} }
/* Align up */ /* Align up */
...@@ -607,6 +610,9 @@ static void *copy_section(const char *name, ...@@ -607,6 +610,9 @@ static void *copy_section(const char *name,
dest += *use; dest += *use;
*use += sechdr->sh_size; *use += sechdr->sh_size;
if (*use > max)
return ERR_PTR(-ENOEXEC);
/* May not actually be in the file (eg. bss). */ /* May not actually be in the file (eg. bss). */
if (sechdr->sh_type != SHT_NOBITS) if (sechdr->sh_type != SHT_NOBITS)
memcpy(dest, base + sechdr->sh_offset, sechdr->sh_size); memcpy(dest, base + sechdr->sh_offset, sechdr->sh_size);
...@@ -773,9 +779,10 @@ static void simplify_symbols(Elf_Shdr *sechdrs, ...@@ -773,9 +779,10 @@ static void simplify_symbols(Elf_Shdr *sechdrs,
/* Get the total allocation size of the init and non-init sections */ /* Get the total allocation size of the init and non-init sections */
static struct sizes get_sizes(const Elf_Ehdr *hdr, static struct sizes get_sizes(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, const Elf_Shdr *sechdrs,
const char *secstrings) const char *secstrings,
unsigned long common_length)
{ {
struct sizes ret = { 0, 0 }; struct sizes ret = { 0, common_length };
unsigned i; unsigned i;
/* Everything marked ALLOC (this includes the exported /* Everything marked ALLOC (this includes the exported
...@@ -933,10 +940,9 @@ static struct module *load_module(void *umod, ...@@ -933,10 +940,9 @@ static struct module *load_module(void *umod,
mod->live = 0; mod->live = 0;
module_unload_init(mod); module_unload_init(mod);
/* How much space will we need? (Common area in core) */ /* How much space will we need? (Common area in first) */
sizes = get_sizes(hdr, sechdrs, secstrings);
common_length = read_commons(hdr, &sechdrs[symindex]); common_length = read_commons(hdr, &sechdrs[symindex]);
sizes.core_size += common_length; sizes = get_sizes(hdr, sechdrs, secstrings, common_length);
/* Set these up, and allow archs to manipulate them. */ /* Set these up, and allow archs to manipulate them. */
mod->core_size = sizes.core_size; mod->core_size = sizes.core_size;
...@@ -963,7 +969,7 @@ static struct module *load_module(void *umod, ...@@ -963,7 +969,7 @@ static struct module *load_module(void *umod,
mod->module_core = ptr; mod->module_core = ptr;
ptr = module_alloc(mod->init_size); ptr = module_alloc(mod->init_size);
if (!ptr) { if (!ptr && mod->init_size) {
err = -ENOMEM; err = -ENOMEM;
goto free_core; goto free_core;
} }
......
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