diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/kernel/module.c b/kernel/module.c index 1d8410b0569f..f9ee37c95dbe 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -592,14 +592,17 @@ static void *copy_section(const char *name, { void *dest; unsigned long *use; + unsigned long max; /* Only copy to init section if there is one */ if (strstr(name, ".init") && mod->module_init) { dest = mod->module_init; use = &used->init_size; + max = mod->init_size; } else { dest = mod->module_core; use = &used->core_size; + max = mod->core_size; } /* Align up */ @@ -607,6 +610,9 @@ static void *copy_section(const char *name, dest += *use; *use += sechdr->sh_size; + if (*use > max) + return ERR_PTR(-ENOEXEC); + /* May not actually be in the file (eg. bss). */ if (sechdr->sh_type != SHT_NOBITS) memcpy(dest, base + sechdr->sh_offset, sechdr->sh_size); @@ -773,9 +779,10 @@ static void simplify_symbols(Elf_Shdr *sechdrs, /* Get the total allocation size of the init and non-init sections */ static struct sizes get_sizes(const Elf_Ehdr *hdr, 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; /* Everything marked ALLOC (this includes the exported @@ -933,10 +940,9 @@ static struct module *load_module(void *umod, mod->live = 0; module_unload_init(mod); - /* How much space will we need? (Common area in core) */ - sizes = get_sizes(hdr, sechdrs, secstrings); + /* How much space will we need? (Common area in first) */ 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. */ mod->core_size = sizes.core_size; @@ -963,7 +969,7 @@ static struct module *load_module(void *umod, mod->module_core = ptr; ptr = module_alloc(mod->init_size); - if (!ptr) { + if (!ptr && mod->init_size) { err = -ENOMEM; goto free_core; } |
