mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 09:02:06 +00:00
modules: don't hand 0 to vmalloc.
In commitd0a21265df
David Rientjes unified various archs' module_alloc implementation (including x86) and removed the graduitous shortcut for size == 0. Then, in commitde7d2b567d
, 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>
This commit is contained in:
parent
54523ec71f
commit
82fab442f5
6 changed files with 18 additions and 28 deletions
|
@ -32,8 +32,6 @@
|
||||||
#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
|
#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
|
||||||
void *module_alloc(unsigned long size)
|
void *module_alloc(unsigned long size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
|
||||||
return NULL;
|
|
||||||
return kmalloc(size, GFP_KERNEL);
|
return kmalloc(size, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -214,8 +214,6 @@ static inline int reassemble_22(int as22)
|
||||||
|
|
||||||
void *module_alloc(unsigned long size)
|
void *module_alloc(unsigned long size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
|
||||||
return NULL;
|
|
||||||
/* using RWX means less protection for modules, but it's
|
/* using RWX means less protection for modules, but it's
|
||||||
* easier than trying to map the text, data, init_text and
|
* easier than trying to map the text, data, init_text and
|
||||||
* init_data correctly */
|
* init_data correctly */
|
||||||
|
|
|
@ -43,10 +43,6 @@ void *module_alloc(unsigned long size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
/* We handle the zero case fine, unlike vmalloc */
|
|
||||||
if (size == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = module_map(size);
|
ret = module_map(size);
|
||||||
if (ret)
|
if (ret)
|
||||||
memset(ret, 0, size);
|
memset(ret, 0, size);
|
||||||
|
|
|
@ -42,8 +42,6 @@ void *module_alloc(unsigned long size)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int npages;
|
int npages;
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
return NULL;
|
|
||||||
npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
|
npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||||
pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
|
pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
|
||||||
if (pages == NULL)
|
if (pages == NULL)
|
||||||
|
|
|
@ -27,9 +27,6 @@ void *module_alloc(unsigned long size)
|
||||||
struct vm_struct *area;
|
struct vm_struct *area;
|
||||||
|
|
||||||
size = PAGE_ALIGN(size);
|
size = PAGE_ALIGN(size);
|
||||||
if (!size)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
|
area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
|
||||||
if (!area)
|
if (!area)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -2377,7 +2377,7 @@ static void dynamic_debug_remove(struct _ddebug *debug)
|
||||||
|
|
||||||
void * __weak module_alloc(unsigned long size)
|
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)
|
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);
|
memset(ptr, 0, mod->core_size);
|
||||||
mod->module_core = ptr;
|
mod->module_core = ptr;
|
||||||
|
|
||||||
ptr = module_alloc_update_bounds(mod->init_size);
|
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
|
* The pointer to this block is stored in the module structure
|
||||||
* scanned as it contains data and code that will be freed
|
* which is inside the block. This block doesn't need to be
|
||||||
* after the module is initialized.
|
* scanned as it contains data and code that will be freed
|
||||||
*/
|
* after the module is initialized.
|
||||||
kmemleak_ignore(ptr);
|
*/
|
||||||
if (!ptr && mod->init_size) {
|
kmemleak_ignore(ptr);
|
||||||
module_free(mod, mod->module_core);
|
if (!ptr) {
|
||||||
return -ENOMEM;
|
module_free(mod, mod->module_core);
|
||||||
}
|
return -ENOMEM;
|
||||||
memset(ptr, 0, mod->init_size);
|
}
|
||||||
mod->module_init = ptr;
|
memset(ptr, 0, mod->init_size);
|
||||||
|
mod->module_init = ptr;
|
||||||
|
} else
|
||||||
|
mod->module_init = NULL;
|
||||||
|
|
||||||
/* Transfer each section which specifies SHF_ALLOC */
|
/* Transfer each section which specifies SHF_ALLOC */
|
||||||
pr_debug("final section addresses:\n");
|
pr_debug("final section addresses:\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue