* [PATCH] mm: module_alloc: check if size is 0
@ 2012-03-01 19:45 Veli-Pekka Peltola
2012-03-01 20:46 ` H. Peter Anvin
2012-03-07 13:09 ` [PATCH v2] " Veli-Pekka Peltola
0 siblings, 2 replies; 8+ messages in thread
From: Veli-Pekka Peltola @ 2012-03-01 19:45 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arm-kernel, linux-mips, Veli-Pekka Peltola, Russell King,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86
After commit de7d2b567d040e3b67fe7121945982f14343213d (mm/vmalloc.c: report
more vmalloc failures) users will get a warning if vmalloc_node_range() is
called with size 0. This happens if module's init size equals to 0. This
patch changes ARM, MIPS and x86 module_alloc() to return NULL before calling
vmalloc_node_range() that would also return NULL and print a warning.
Signed-off-by: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
---
I found this with ARM but after checking out various implementations of
module_alloc() I thought it would be better to fix all at once.
One way to replicate the warning:
compile kernel with CONFIG_KALLSYMS=n
insmod module without init, I used usb-common.ko
arch/arm/kernel/module.c | 4 ++--
arch/mips/kernel/module.c | 4 ++--
arch/x86/kernel/module.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 1e9be5d..d44d212 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -39,8 +39,8 @@
#ifdef CONFIG_MMU
void *module_alloc(unsigned long size)
{
- return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
+ return size == 0 ? NULL : __vmalloc_node_range(size, 1, MODULES_VADDR,
+ MODULES_END, GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
__builtin_return_address(0));
}
#endif
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index a5066b1..cd768e9 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -47,8 +47,8 @@ static DEFINE_SPINLOCK(dbe_lock);
#ifdef MODULE_START
void *module_alloc(unsigned long size)
{
- return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
- GFP_KERNEL, PAGE_KERNEL, -1,
+ return size == 0 ? NULL : __vmalloc_node_range(size, 1, MODULE_START,
+ MODULE_END, GFP_KERNEL, PAGE_KERNEL, -1,
__builtin_return_address(0));
}
#endif
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 925179f..bff6118 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -38,7 +38,7 @@
void *module_alloc(unsigned long size)
{
- if (PAGE_ALIGN(size) > MODULES_LEN)
+ if (size == 0 || PAGE_ALIGN(size) > MODULES_LEN)
return NULL;
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
--
1.7.5.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] mm: module_alloc: check if size is 0
2012-03-01 19:45 [PATCH] mm: module_alloc: check if size is 0 Veli-Pekka Peltola
@ 2012-03-01 20:46 ` H. Peter Anvin
2012-03-07 13:09 ` [PATCH v2] " Veli-Pekka Peltola
1 sibling, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2012-03-01 20:46 UTC (permalink / raw)
To: Veli-Pekka Peltola
Cc: linux-kernel, linux-arm-kernel, linux-mips, Russell King,
Thomas Gleixner, Ingo Molnar, x86
On 03/01/2012 11:45 AM, Veli-Pekka Peltola wrote:
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index 1e9be5d..d44d212 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -39,8 +39,8 @@
> #ifdef CONFIG_MMU
> void *module_alloc(unsigned long size)
> {
> - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
> - GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
> + return size == 0 ? NULL : __vmalloc_node_range(size, 1, MODULES_VADDR,
> + MODULES_END, GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
> __builtin_return_address(0));
> }
> #endif
> diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
> index a5066b1..cd768e9 100644
> --- a/arch/mips/kernel/module.c
> +++ b/arch/mips/kernel/module.c
> @@ -47,8 +47,8 @@ static DEFINE_SPINLOCK(dbe_lock);
> #ifdef MODULE_START
> void *module_alloc(unsigned long size)
> {
> - return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
> - GFP_KERNEL, PAGE_KERNEL, -1,
> + return size == 0 ? NULL : __vmalloc_node_range(size, 1, MODULE_START,
> + MODULE_END, GFP_KERNEL, PAGE_KERNEL, -1,
> __builtin_return_address(0));
> }
> #endif
> diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
> index 925179f..bff6118 100644
> --- a/arch/x86/kernel/module.c
> +++ b/arch/x86/kernel/module.c
> @@ -38,7 +38,7 @@
>
> void *module_alloc(unsigned long size)
> {
> - if (PAGE_ALIGN(size) > MODULES_LEN)
> + if (size == 0 || PAGE_ALIGN(size) > MODULES_LEN)
> return NULL;
> return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
> GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
Looks good stylistically but really awkward technically.
I would like to suggest using the idiom:
if (!size)
return NULL;
... consistently; combined with the PAGE_ALIGN() clause for x86 is fine too.
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] mm: module_alloc: check if size is 0
2012-03-01 19:45 [PATCH] mm: module_alloc: check if size is 0 Veli-Pekka Peltola
2012-03-01 20:46 ` H. Peter Anvin
@ 2012-03-07 13:09 ` Veli-Pekka Peltola
2012-03-19 15:36 ` Veli-Pekka Peltola
2013-06-27 9:39 ` Ralf Baechle
1 sibling, 2 replies; 8+ messages in thread
From: Veli-Pekka Peltola @ 2012-03-07 13:09 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arm-kernel, linux-mips, Veli-Pekka Peltola, Russell King,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86
After commit de7d2b567d040e3b67fe7121945982f14343213d (mm/vmalloc.c: report
more vmalloc failures) users will get a warning if vmalloc_node_range() is
called with size 0. This happens if module's init size equals to 0. This
patch changes ARM, MIPS and x86 module_alloc() to return NULL before calling
vmalloc_node_range() that would also return NULL and print a warning.
Signed-off-by: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
---
I found this with ARM but after checking out various implementations of
module_alloc() I thought it would be better to fix all at once.
One way to replicate the warning:
compile kernel with CONFIG_KALLSYMS=n
insmod a module without init, I used usb-common.ko
Changes since v1:
- changed style as hpa suggested
arch/arm/kernel/module.c | 2 ++
arch/mips/kernel/module.c | 2 ++
arch/x86/kernel/module.c | 2 +-
3 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 1e9be5d..17648e2 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -39,6 +39,8 @@
#ifdef CONFIG_MMU
void *module_alloc(unsigned long size)
{
+ if (!size)
+ return NULL;
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
__builtin_return_address(0));
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index a5066b1..1a51de1 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -47,6 +47,8 @@ static DEFINE_SPINLOCK(dbe_lock);
#ifdef MODULE_START
void *module_alloc(unsigned long size)
{
+ if (!size)
+ return NULL;
return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
GFP_KERNEL, PAGE_KERNEL, -1,
__builtin_return_address(0));
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 925179f..fd44d69 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -38,7 +38,7 @@
void *module_alloc(unsigned long size)
{
- if (PAGE_ALIGN(size) > MODULES_LEN)
+ if (!size || PAGE_ALIGN(size) > MODULES_LEN)
return NULL;
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
--
1.7.5.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: module_alloc: check if size is 0
2012-03-07 13:09 ` [PATCH v2] " Veli-Pekka Peltola
@ 2012-03-19 15:36 ` Veli-Pekka Peltola
2013-06-27 9:39 ` Ralf Baechle
1 sibling, 0 replies; 8+ messages in thread
From: Veli-Pekka Peltola @ 2012-03-19 15:36 UTC (permalink / raw)
To: linux-kernel
Cc: linux-arm-kernel, linux-mips, Russell King, Thomas Gleixner,
Ingo Molnar, H. Peter Anvin, x86
Hi,
On 03/07/2012 03:09 PM, Veli-Pekka Peltola wrote:
> After commit de7d2b567d040e3b67fe7121945982f14343213d (mm/vmalloc.c: report
> more vmalloc failures) users will get a warning if vmalloc_node_range() is
> called with size 0. This happens if module's init size equals to 0. This
> patch changes ARM, MIPS and x86 module_alloc() to return NULL before calling
> vmalloc_node_range() that would also return NULL and print a warning.
>
> Signed-off-by: Veli-Pekka Peltola<veli-pekka.peltola@bluegiga.com>
> Cc: Russell King<linux@arm.linux.org.uk>
> Cc: Thomas Gleixner<tglx@linutronix.de>
> Cc: Ingo Molnar<mingo@redhat.com>
> Cc: "H. Peter Anvin"<hpa@zytor.com>
> Cc: x86@kernel.org
> ---
> I found this with ARM but after checking out various implementations of
> module_alloc() I thought it would be better to fix all at once.
>
> One way to replicate the warning:
> compile kernel with CONFIG_KALLSYMS=n
> insmod a module without init, I used usb-common.ko
>
> Changes since v1:
> - changed style as hpa suggested
>
> arch/arm/kernel/module.c | 2 ++
> arch/mips/kernel/module.c | 2 ++
> arch/x86/kernel/module.c | 2 +-
> 3 files changed, 5 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index 1e9be5d..17648e2 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -39,6 +39,8 @@
> #ifdef CONFIG_MMU
> void *module_alloc(unsigned long size)
> {
> + if (!size)
> + return NULL;
> return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
> GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
> __builtin_return_address(0));
> diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
> index a5066b1..1a51de1 100644
> --- a/arch/mips/kernel/module.c
> +++ b/arch/mips/kernel/module.c
> @@ -47,6 +47,8 @@ static DEFINE_SPINLOCK(dbe_lock);
> #ifdef MODULE_START
> void *module_alloc(unsigned long size)
> {
> + if (!size)
> + return NULL;
> return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
> GFP_KERNEL, PAGE_KERNEL, -1,
> __builtin_return_address(0));
> diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
> index 925179f..fd44d69 100644
> --- a/arch/x86/kernel/module.c
> +++ b/arch/x86/kernel/module.c
> @@ -38,7 +38,7 @@
>
> void *module_alloc(unsigned long size)
> {
> - if (PAGE_ALIGN(size)> MODULES_LEN)
> + if (!size || PAGE_ALIGN(size)> MODULES_LEN)
> return NULL;
> return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
> GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
Any comments on this? Should I split all architectures to separate patches?
I just tested 3.3 on ARM and x86, both printed a warning and call trace
without this patch.
--
Veli-Pekka Peltola
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: module_alloc: check if size is 0
2012-03-07 13:09 ` [PATCH v2] " Veli-Pekka Peltola
2012-03-19 15:36 ` Veli-Pekka Peltola
@ 2013-06-27 9:39 ` Ralf Baechle
2013-06-27 22:23 ` Andrew Morton
1 sibling, 1 reply; 8+ messages in thread
From: Ralf Baechle @ 2013-06-27 9:39 UTC (permalink / raw)
To: Veli-Pekka Peltola
Cc: linux-kernel, linux-arm-kernel, linux-mips, Russell King,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86, Peter Zijlstra,
Rusty Russell, Andrew Morton
Warming up an ancient thread because the discussion seems to have just
stalled at some point and I still have this patch bitrotting in patchwork.
The original thread can be found at:
http://www.linux-mips.org/archives/linux-mips/2012-03/msg00006.html
http://www.linux-mips.org/archives/linux-mips/2012-03/msg00028.html
On Wed, Mar 07, 2012 at 03:09:28PM +0200, Veli-Pekka Peltola wrote:
> After commit de7d2b567d040e3b67fe7121945982f14343213d (mm/vmalloc.c: report
> more vmalloc failures) users will get a warning if vmalloc_node_range() is
> called with size 0. This happens if module's init size equals to 0. This
> patch changes ARM, MIPS and x86 module_alloc() to return NULL before calling
> vmalloc_node_range() that would also return NULL and print a warning.
>
> Signed-off-by: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> ---
> I found this with ARM but after checking out various implementations of
> module_alloc() I thought it would be better to fix all at once.
>
> One way to replicate the warning:
> compile kernel with CONFIG_KALLSYMS=n
> insmod a module without init, I used usb-common.ko
I didn't try to reproduce the issue but the code in question doesn't seem
to have changed so the issue should still persist.
Imho de7d2b567d040e3b67fe7121945982f14343213d [mm/vmalloc.c: report more
vmalloc failures] is overly strict in that it also reports zero-sized
allocations. I consider such allocations stupid but legitimiate and often
better preferrable over having to scatter checks for zero size all over
place. So maybe something like below patch?
Thanks,
Ralf
---
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
mm/vmalloc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d365724..e58ca10 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1679,7 +1679,10 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
unsigned long real_size = size;
size = PAGE_ALIGN(size);
- if (!size || (size >> PAGE_SHIFT) > totalram_pages)
+ if (unlikely(!size))
+ return NULL;
+
+ if ((size >> PAGE_SHIFT) > totalram_pages)
goto fail;
area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST,
@@ -1711,6 +1714,7 @@ fail:
warn_alloc_failed(gfp_mask, 0,
"vmalloc: allocation failure: %lu bytes\n",
real_size);
+
return NULL;
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: module_alloc: check if size is 0
2013-06-27 9:39 ` Ralf Baechle
@ 2013-06-27 22:23 ` Andrew Morton
2013-06-27 22:46 ` Joe Perches
0 siblings, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2013-06-27 22:23 UTC (permalink / raw)
To: Ralf Baechle
Cc: Veli-Pekka Peltola, linux-kernel, linux-arm-kernel, linux-mips,
Russell King, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
Peter Zijlstra, Rusty Russell
On Thu, 27 Jun 2013 11:39:17 +0200 Ralf Baechle <ralf@linux-mips.org> wrote:
> Imho de7d2b567d040e3b67fe7121945982f14343213d [mm/vmalloc.c: report more
> vmalloc failures] is overly strict in that it also reports zero-sized
> allocations. I consider such allocations stupid but legitimiate and often
> better preferrable over having to scatter checks for zero size all over
> place. So maybe something like below patch?
>
> ...
>
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1679,7 +1679,10 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
> unsigned long real_size = size;
>
> size = PAGE_ALIGN(size);
> - if (!size || (size >> PAGE_SHIFT) > totalram_pages)
> + if (unlikely(!size))
> + return NULL;
> +
> + if ((size >> PAGE_SHIFT) > totalram_pages)
> goto fail;
>
> area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST,
> @@ -1711,6 +1714,7 @@ fail:
> warn_alloc_failed(gfp_mask, 0,
> "vmalloc: allocation failure: %lu bytes\n",
> real_size);
> +
> return NULL;
> }
If the caller actually dereferences the returned pointer the kernel
will go oops, which should provide adequate notification of a
programming error ;) But all callers should be checking the return
value. So I worry about the by-far-most-common case where code does
size = some_screwed_up_calculation();
p = vmalloc(size);
if (!p)
return -ENOMEM;
So the mistake gets propagated back to who-knows-where as memory
exhaustion and thereby becomes a lot harder to diagnose.
How many callsites really truly need to be edited to avoid the warning?
Veli-Pekka's original patch would be neater if we were to add a new
void *__vmalloc_node_range_zero_size_ok(<args>)
{
if (size == 0)
return NULL;
return __vmalloc_node_range(<args>);
}
(with a better name than __vmalloc_node_range_zero_size_ok!)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: module_alloc: check if size is 0
2013-06-27 22:23 ` Andrew Morton
@ 2013-06-27 22:46 ` Joe Perches
2013-07-01 3:18 ` Rusty Russell
0 siblings, 1 reply; 8+ messages in thread
From: Joe Perches @ 2013-06-27 22:46 UTC (permalink / raw)
To: Andrew Morton
Cc: Ralf Baechle, Veli-Pekka Peltola, linux-kernel, linux-arm-kernel,
linux-mips, Russell King, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, x86, Peter Zijlstra, Rusty Russell
On Thu, 2013-06-27 at 15:23 -0700, Andrew Morton wrote:
> On Thu, 27 Jun 2013 11:39:17 +0200 Ralf Baechle <ralf@linux-mips.org> wrote:
[]
> Veli-Pekka's original patch would be neater if we were to add a new
>
> void *__vmalloc_node_range_zero_size_ok(<args>)
> {
> if (size == 0)
> return NULL;
I believe you mean
return ZERO_SIZE_PTR;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] mm: module_alloc: check if size is 0
2013-06-27 22:46 ` Joe Perches
@ 2013-07-01 3:18 ` Rusty Russell
0 siblings, 0 replies; 8+ messages in thread
From: Rusty Russell @ 2013-07-01 3:18 UTC (permalink / raw)
To: Joe Perches, Andrew Morton
Cc: Ralf Baechle, Veli-Pekka Peltola, linux-kernel, linux-arm-kernel,
linux-mips, Russell King, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, x86, Peter Zijlstra
Joe Perches <joe@perches.com> writes:
> On Thu, 2013-06-27 at 15:23 -0700, Andrew Morton wrote:
>> On Thu, 27 Jun 2013 11:39:17 +0200 Ralf Baechle <ralf@linux-mips.org> wrote:
> []
>> Veli-Pekka's original patch would be neater if we were to add a new
>>
>> void *__vmalloc_node_range_zero_size_ok(<args>)
>> {
>> if (size == 0)
>> return NULL;
>
> I believe you mean
> return ZERO_SIZE_PTR;
Yes, this is the Right Fix.
Thanks,
Rusty.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-07-01 8:53 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-01 19:45 [PATCH] mm: module_alloc: check if size is 0 Veli-Pekka Peltola
2012-03-01 20:46 ` H. Peter Anvin
2012-03-07 13:09 ` [PATCH v2] " Veli-Pekka Peltola
2012-03-19 15:36 ` Veli-Pekka Peltola
2013-06-27 9:39 ` Ralf Baechle
2013-06-27 22:23 ` Andrew Morton
2013-06-27 22:46 ` Joe Perches
2013-07-01 3:18 ` Rusty Russell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox