Commit 82fab442f5322b016f72891c0db2436c6a6c20b7
1 parent
54523ec71f
Exists in
master
and in
20 other branches
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>
Showing 6 changed files with 18 additions and 28 deletions Side-by-side Diff
arch/cris/kernel/module.c
arch/parisc/kernel/module.c
arch/sparc/kernel/module.c
arch/tile/kernel/module.c
arch/unicore32/kernel/module.c
kernel/module.c
... | ... | @@ -2377,7 +2377,7 @@ |
2377 | 2377 | |
2378 | 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 | 2383 | static void *module_alloc_update_bounds(unsigned long size) |
... | ... | @@ -2793,20 +2793,23 @@ |
2793 | 2793 | memset(ptr, 0, mod->core_size); |
2794 | 2794 | mod->module_core = ptr; |
2795 | 2795 | |
2796 | - ptr = module_alloc_update_bounds(mod->init_size); | |
2797 | - /* | |
2798 | - * The pointer to this block is stored in the module structure | |
2799 | - * which is inside the block. This block doesn't need to be | |
2800 | - * scanned as it contains data and code that will be freed | |
2801 | - * after the module is initialized. | |
2802 | - */ | |
2803 | - kmemleak_ignore(ptr); | |
2804 | - if (!ptr && mod->init_size) { | |
2805 | - module_free(mod, mod->module_core); | |
2806 | - return -ENOMEM; | |
2807 | - } | |
2808 | - memset(ptr, 0, mod->init_size); | |
2809 | - mod->module_init = ptr; | |
2796 | + if (mod->init_size) { | |
2797 | + ptr = module_alloc_update_bounds(mod->init_size); | |
2798 | + /* | |
2799 | + * The pointer to this block is stored in the module structure | |
2800 | + * which is inside the block. This block doesn't need to be | |
2801 | + * scanned as it contains data and code that will be freed | |
2802 | + * after the module is initialized. | |
2803 | + */ | |
2804 | + kmemleak_ignore(ptr); | |
2805 | + if (!ptr) { | |
2806 | + module_free(mod, mod->module_core); | |
2807 | + return -ENOMEM; | |
2808 | + } | |
2809 | + memset(ptr, 0, mod->init_size); | |
2810 | + mod->module_init = ptr; | |
2811 | + } else | |
2812 | + mod->module_init = NULL; | |
2810 | 2813 | |
2811 | 2814 | /* Transfer each section which specifies SHF_ALLOC */ |
2812 | 2815 | pr_debug("final section addresses:\n"); |