]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
modules: don't hand 0 to vmalloc.
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 10 Dec 2012 23:08:33 +0000 (09:38 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 14 Dec 2012 02:36:43 +0000 (13:06 +1030)
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>
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

index 37400f5869e6137d780be5326ab49875d939f15c..51123f985eb5862a83bf7afcfc22e4bce2ecbda7 100644 (file)
@@ -32,8 +32,6 @@
 #ifdef CONFIG_ETRAX_KMALLOCED_MODULES
 void *module_alloc(unsigned long size)
 {
-       if (size == 0)
-               return NULL;
        return kmalloc(size, GFP_KERNEL);
 }
 
index 5e34ccf39a49eba54d9a0cbf74c2055ed439cb43..2a625fb063e1537bcdff9dd18cc10dde87ec535f 100644 (file)
@@ -214,8 +214,6 @@ static inline int reassemble_22(int as22)
 
 void *module_alloc(unsigned long size)
 {
-       if (size == 0)
-               return NULL;
        /* using RWX means less protection for modules, but it's
         * easier than trying to map the text, data, init_text and
         * init_data correctly */
index f1ddc0d2367947d850e863aa4d0a897705074574..4435488ebe258580afd7177dc61579e2c3727044 100644 (file)
@@ -43,10 +43,6 @@ void *module_alloc(unsigned long size)
 {
        void *ret;
 
-       /* We handle the zero case fine, unlike vmalloc */
-       if (size == 0)
-               return NULL;
-
        ret = module_map(size);
        if (ret)
                memset(ret, 0, size);
index 243ffebe38d69a510f16e53083c49b46f3e6531b..4918d91bc3a660942a6aec8585be2bb41425d3df 100644 (file)
@@ -42,8 +42,6 @@ void *module_alloc(unsigned long size)
        int i = 0;
        int npages;
 
-       if (size == 0)
-               return NULL;
        npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
        pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
        if (pages == NULL)
index 8fbe8577f5e6902d07667ad426bdc6f2f5b8bfe9..16bd1495b9342472f86c3610fefbce27cce87000 100644 (file)
@@ -27,9 +27,6 @@ void *module_alloc(unsigned long size)
        struct vm_struct *area;
 
        size = PAGE_ALIGN(size);
-       if (!size)
-               return NULL;
-
        area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
        if (!area)
                return NULL;
index 79a526dd1b113f92572a7899919ac556b90981e1..4542ff3f7ef9668bf7e163eed50080f47953745d 100644 (file)
@@ -2377,7 +2377,7 @@ static void dynamic_debug_remove(struct _ddebug *debug)
 
 void * __weak module_alloc(unsigned long size)
 {
-       return size == 0 ? NULL : vmalloc_exec(size);
+       return vmalloc_exec(size);
 }
 
 static void *module_alloc_update_bounds(unsigned long size)
@@ -2793,20 +2793,23 @@ static int move_module(struct module *mod, struct load_info *info)
        memset(ptr, 0, mod->core_size);
        mod->module_core = ptr;
 
-       ptr = module_alloc_update_bounds(mod->init_size);
-       /*
-        * The pointer to this block is stored in the module structure
-        * which is inside the block. This block doesn't need to be
-        * scanned as it contains data and code that will be freed
-        * after the module is initialized.
-        */
-       kmemleak_ignore(ptr);
-       if (!ptr && mod->init_size) {
-               module_free(mod, mod->module_core);
-               return -ENOMEM;
-       }
-       memset(ptr, 0, mod->init_size);
-       mod->module_init = ptr;
+       if (mod->init_size) {
+               ptr = module_alloc_update_bounds(mod->init_size);
+               /*
+                * The pointer to this block is stored in the module structure
+                * which is inside the block. This block doesn't need to be
+                * scanned as it contains data and code that will be freed
+                * after the module is initialized.
+                */
+               kmemleak_ignore(ptr);
+               if (!ptr) {
+                       module_free(mod, mod->module_core);
+                       return -ENOMEM;
+               }
+               memset(ptr, 0, mod->init_size);
+               mod->module_init = ptr;
+       } else
+               mod->module_init = NULL;
 
        /* Transfer each section which specifies SHF_ALLOC */
        pr_debug("final section addresses:\n");