Commit 82fab442f5322b016f72891c0db2436c6a6c20b7

Authored by Rusty Russell
1 parent 54523ec71f

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
... ... @@ -32,8 +32,6 @@
32 32 #ifdef CONFIG_ETRAX_KMALLOCED_MODULES
33 33 void *module_alloc(unsigned long size)
34 34 {
35   - if (size == 0)
36   - return NULL;
37 35 return kmalloc(size, GFP_KERNEL);
38 36 }
39 37  
arch/parisc/kernel/module.c
... ... @@ -214,8 +214,6 @@
214 214  
215 215 void *module_alloc(unsigned long size)
216 216 {
217   - if (size == 0)
218   - return NULL;
219 217 /* using RWX means less protection for modules, but it's
220 218 * easier than trying to map the text, data, init_text and
221 219 * init_data correctly */
arch/sparc/kernel/module.c
... ... @@ -43,10 +43,6 @@
43 43 {
44 44 void *ret;
45 45  
46   - /* We handle the zero case fine, unlike vmalloc */
47   - if (size == 0)
48   - return NULL;
49   -
50 46 ret = module_map(size);
51 47 if (ret)
52 48 memset(ret, 0, size);
arch/tile/kernel/module.c
... ... @@ -42,8 +42,6 @@
42 42 int i = 0;
43 43 int npages;
44 44  
45   - if (size == 0)
46   - return NULL;
47 45 npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
48 46 pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
49 47 if (pages == NULL)
arch/unicore32/kernel/module.c
... ... @@ -27,9 +27,6 @@
27 27 struct vm_struct *area;
28 28  
29 29 size = PAGE_ALIGN(size);
30   - if (!size)
31   - return NULL;
32   -
33 30 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
34 31 if (!area)
35 32 return NULL;
... ... @@ -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");