diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2012-12-10 18:08:33 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-12-13 21:36:43 -0500 |
commit | 82fab442f5322b016f72891c0db2436c6a6c20b7 (patch) | |
tree | 1b55bbf22569cf721c4bc13dc8f96652bad50a26 /kernel | |
parent | 54523ec71f8ce99accae97c74152f14f261f7e18 (diff) |
modules: don't hand 0 to vmalloc.
In commit d0a21265dfb5fa8a David Rientjes unified various archs'
module_alloc implementation (including x86) and removed the graduitous
shortcut for size == 0.
Then, in commit de7d2b567d040e3b, Joe Perches added a warning for
zero-length vmallocs, which can happen without kallsyms on modules
with no init sections (eg. zlib_deflate).
Fix this once and for all; the module code has to handle zero length
anyway, so get it right at the caller and remove the now-gratuitous
checks within the arch-specific module_alloc implementations.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42608
Reported-by: Conrad Kostecki <ConiKost@gmx.de>
Cc: David Rientjes <rientjes@google.com>
Cc: Joe Perches <joe@perches.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/module.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/kernel/module.c b/kernel/module.c index 79a526dd1b11..4542ff3f7ef9 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2377,7 +2377,7 @@ static void dynamic_debug_remove(struct _ddebug *debug) | |||
2377 | 2377 | ||
2378 | void * __weak module_alloc(unsigned long size) | 2378 | void * __weak module_alloc(unsigned long size) |
2379 | { | 2379 | { |
2380 | return size == 0 ? NULL : vmalloc_exec(size); | 2380 | return vmalloc_exec(size); |
2381 | } | 2381 | } |
2382 | 2382 | ||
2383 | static void *module_alloc_update_bounds(unsigned long size) | 2383 | static void *module_alloc_update_bounds(unsigned long size) |
@@ -2793,20 +2793,23 @@ static int move_module(struct module *mod, struct load_info *info) | |||
2793 | memset(ptr, 0, mod->core_size); | 2793 | memset(ptr, 0, mod->core_size); |
2794 | mod->module_core = ptr; | 2794 | mod->module_core = ptr; |
2795 | 2795 | ||
2796 | ptr = module_alloc_update_bounds(mod->init_size); | 2796 | if (mod->init_size) { |
2797 | /* | 2797 | ptr = module_alloc_update_bounds(mod->init_size); |
2798 | * The pointer to this block is stored in the module structure | 2798 | /* |
2799 | * which is inside the block. This block doesn't need to be | 2799 | * The pointer to this block is stored in the module structure |
2800 | * scanned as it contains data and code that will be freed | 2800 | * which is inside the block. This block doesn't need to be |
2801 | * after the module is initialized. | 2801 | * scanned as it contains data and code that will be freed |
2802 | */ | 2802 | * after the module is initialized. |
2803 | kmemleak_ignore(ptr); | 2803 | */ |
2804 | if (!ptr && mod->init_size) { | 2804 | kmemleak_ignore(ptr); |
2805 | module_free(mod, mod->module_core); | 2805 | if (!ptr) { |
2806 | return -ENOMEM; | 2806 | module_free(mod, mod->module_core); |
2807 | } | 2807 | return -ENOMEM; |
2808 | memset(ptr, 0, mod->init_size); | 2808 | } |
2809 | mod->module_init = ptr; | 2809 | memset(ptr, 0, mod->init_size); |
2810 | mod->module_init = ptr; | ||
2811 | } else | ||
2812 | mod->module_init = NULL; | ||
2810 | 2813 | ||
2811 | /* Transfer each section which specifies SHF_ALLOC */ | 2814 | /* Transfer each section which specifies SHF_ALLOC */ |
2812 | pr_debug("final section addresses:\n"); | 2815 | pr_debug("final section addresses:\n"); |