* [PATCH v2] avoid null pointer access in vm_struct
@ 2011-08-19 10:51 Mitsuo Hayasaka
2011-08-19 18:53 ` Paul E. McKenney
2011-08-19 22:52 ` Andrew Morton
0 siblings, 2 replies; 4+ messages in thread
From: Mitsuo Hayasaka @ 2011-08-19 10:51 UTC (permalink / raw)
To: linux-mm, linux-kernel
Cc: KOSAKI Motohiro, yrl.pp-manager.tt, Mitsuo Hayasaka,
Andrew Morton, Namhyung Kim, David Rientjes, Paul E. McKenney,
Jeremy Fitzhardinge
The /proc/vmallocinfo shows information about vmalloc allocations in vmlist
that is a linklist of vm_struct. It, however, may access pages field of
vm_struct where a page was not allocated, which results in a null pointer
access and leads to a kernel panic.
Why this happen:
In __vmalloc_area_node(), the nr_pages field of vm_struct are set to the
expected number of pages to be allocated, before the actual pages
allocations. At the same time, when the /proc/vmallocinfo is read, it
accesses the pages field of vm_struct according to the nr_pages field at
show_numa_info(). Thus, a null pointer access happens.
Patch:
This patch sets nr_pages field of vm_struct AFTER the pages allocations
finished in __vmalloc_area_node(). So, it can avoid accessing the pages
field with unallocated page when show_numa_info() is called.
Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: David Rientjes <rientjes@google.com>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
mm/vmalloc.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7ef0903..49d8aed 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1529,7 +1529,6 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
nr_pages = (area->size - PAGE_SIZE) >> PAGE_SHIFT;
array_size = (nr_pages * sizeof(struct page *));
- area->nr_pages = nr_pages;
/* Please note that the recursion is strictly bounded. */
if (array_size > PAGE_SIZE) {
pages = __vmalloc_node(array_size, 1, nested_gfp|__GFP_HIGHMEM,
@@ -1538,15 +1537,15 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
} else {
pages = kmalloc_node(array_size, nested_gfp, node);
}
- area->pages = pages;
- area->caller = caller;
- if (!area->pages) {
+ if (!pages) {
remove_vm_area(area->addr);
kfree(area);
return NULL;
}
+ area->pages = pages;
+ area->caller = caller;
- for (i = 0; i < area->nr_pages; i++) {
+ for (i = 0; i < nr_pages; i++) {
struct page *page;
gfp_t tmp_mask = gfp_mask | __GFP_NOWARN;
@@ -1562,6 +1561,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
}
area->pages[i] = page;
}
+ area->nr_pages = nr_pages;
if (map_vm_area(area, prot, &pages))
goto fail;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v2] avoid null pointer access in vm_struct
2011-08-19 10:51 [PATCH v2] avoid null pointer access in vm_struct Mitsuo Hayasaka
@ 2011-08-19 18:53 ` Paul E. McKenney
2011-08-19 22:52 ` Andrew Morton
1 sibling, 0 replies; 4+ messages in thread
From: Paul E. McKenney @ 2011-08-19 18:53 UTC (permalink / raw)
To: Mitsuo Hayasaka
Cc: linux-mm, linux-kernel, KOSAKI Motohiro, yrl.pp-manager.tt,
Andrew Morton, Namhyung Kim, David Rientjes, Jeremy Fitzhardinge
On Fri, Aug 19, 2011 at 07:51:33PM +0900, Mitsuo Hayasaka wrote:
> The /proc/vmallocinfo shows information about vmalloc allocations in vmlist
> that is a linklist of vm_struct. It, however, may access pages field of
> vm_struct where a page was not allocated, which results in a null pointer
> access and leads to a kernel panic.
>
> Why this happen:
> In __vmalloc_area_node(), the nr_pages field of vm_struct are set to the
> expected number of pages to be allocated, before the actual pages
> allocations. At the same time, when the /proc/vmallocinfo is read, it
> accesses the pages field of vm_struct according to the nr_pages field at
> show_numa_info(). Thus, a null pointer access happens.
>
> Patch:
> This patch sets nr_pages field of vm_struct AFTER the pages allocations
> finished in __vmalloc_area_node(). So, it can avoid accessing the pages
> field with unallocated page when show_numa_info() is called.
One question below...
> Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Namhyung Kim <namhyung@gmail.com>
> Cc: David Rientjes <rientjes@google.com>
> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> Cc: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
> ---
>
> mm/vmalloc.c | 10 +++++-----
> 1 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 7ef0903..49d8aed 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1529,7 +1529,6 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
> nr_pages = (area->size - PAGE_SIZE) >> PAGE_SHIFT;
> array_size = (nr_pages * sizeof(struct page *));
>
> - area->nr_pages = nr_pages;
> /* Please note that the recursion is strictly bounded. */
> if (array_size > PAGE_SIZE) {
> pages = __vmalloc_node(array_size, 1, nested_gfp|__GFP_HIGHMEM,
> @@ -1538,15 +1537,15 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
> } else {
> pages = kmalloc_node(array_size, nested_gfp, node);
> }
> - area->pages = pages;
> - area->caller = caller;
> - if (!area->pages) {
> + if (!pages) {
> remove_vm_area(area->addr);
> kfree(area);
> return NULL;
> }
> + area->pages = pages;
> + area->caller = caller;
>
> - for (i = 0; i < area->nr_pages; i++) {
> + for (i = 0; i < nr_pages; i++) {
> struct page *page;
> gfp_t tmp_mask = gfp_mask | __GFP_NOWARN;
>
> @@ -1562,6 +1561,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
> }
> area->pages[i] = page;
> }
Don't we need something here to prevent the compiler and/or the CPU
from reordering the assignment? Or am I missing how this is otherwise
prevented?
> + area->nr_pages = nr_pages;
>
> if (map_vm_area(area, prot, &pages))
> goto fail;
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v2] avoid null pointer access in vm_struct
2011-08-19 10:51 [PATCH v2] avoid null pointer access in vm_struct Mitsuo Hayasaka
2011-08-19 18:53 ` Paul E. McKenney
@ 2011-08-19 22:52 ` Andrew Morton
2011-08-20 4:22 ` HAYASAKA Mitsuo
1 sibling, 1 reply; 4+ messages in thread
From: Andrew Morton @ 2011-08-19 22:52 UTC (permalink / raw)
To: Mitsuo Hayasaka
Cc: linux-mm, linux-kernel, KOSAKI Motohiro, yrl.pp-manager.tt,
Namhyung Kim, David Rientjes, Paul E. McKenney,
Jeremy Fitzhardinge
On Fri, 19 Aug 2011 19:51:33 +0900
Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com> wrote:
> The /proc/vmallocinfo shows information about vmalloc allocations in vmlist
> that is a linklist of vm_struct. It, however, may access pages field of
> vm_struct where a page was not allocated, which results in a null pointer
> access and leads to a kernel panic.
>
> Why this happen:
> In __vmalloc_area_node(), the nr_pages field of vm_struct are set to the
> expected number of pages to be allocated, before the actual pages
> allocations. At the same time, when the /proc/vmallocinfo is read, it
> accesses the pages field of vm_struct according to the nr_pages field at
> show_numa_info(). Thus, a null pointer access happens.
>
> Patch:
> This patch sets nr_pages field of vm_struct AFTER the pages allocations
> finished in __vmalloc_area_node(). So, it can avoid accessing the pages
> field with unallocated page when show_numa_info() is called.
I think this is still just a workaround to fix up the real bug, and
that the real bug is that the vm_struct is installed into the vmlist
*before* it is fully initialised. It's just wrong to insert an object
into a globally-visible list and to then start populating it! If we
were instead to fully initialise the vm_struct and *then* insert it
into vmlist, the bug is fixed.
Also I'd agree with Paul's concern regarding cross-CPU memory ordering.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] avoid null pointer access in vm_struct
2011-08-19 22:52 ` Andrew Morton
@ 2011-08-20 4:22 ` HAYASAKA Mitsuo
0 siblings, 0 replies; 4+ messages in thread
From: HAYASAKA Mitsuo @ 2011-08-20 4:22 UTC (permalink / raw)
To: Andrew Morton, Paul E. McKenney
Cc: linux-mm, linux-kernel, KOSAKI Motohiro, yrl.pp-manager.tt,
Namhyung Kim, David Rientjes, Jeremy Fitzhardinge
Hi Paul and Andrew,
(2011/08/20 3:53), Paul E. McKenney wrote:
>> @@ -1562,6 +1561,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
>> }
>> area->pages[i] = page;
>> }
> Don't we need something here to prevent the compiler and/or the CPU
> from reordering the assignment? Or am I missing how this is otherwise
> prevented?
>
(2011/08/20 7:52), Andrew Morton wrote:
> I think this is still just a workaround to fix up the real bug, and
> that the real bug is that the vm_struct is installed into the vmlist
> *before* it is fully initialised. It's just wrong to insert an object
> into a globally-visible list and to then start populating it! If we
> were instead to fully initialise the vm_struct and *then* insert it
> into vmlist, the bug is fixed.
>
> Also I'd agree with Paul's concern regarding cross-CPU memory ordering.
>
I deeply agreed with both of your concern and comments.
I'd like to create the patch where the vm_struct is installed into
the vmlist *after* it is fully initialized.
Thanks.
(2011/08/20 7:52), Andrew Morton wrote:
> On Fri, 19 Aug 2011 19:51:33 +0900
> Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com> wrote:
>
>> The /proc/vmallocinfo shows information about vmalloc allocations in vmlist
>> that is a linklist of vm_struct. It, however, may access pages field of
>> vm_struct where a page was not allocated, which results in a null pointer
>> access and leads to a kernel panic.
>>
>> Why this happen:
>> In __vmalloc_area_node(), the nr_pages field of vm_struct are set to the
>> expected number of pages to be allocated, before the actual pages
>> allocations. At the same time, when the /proc/vmallocinfo is read, it
>> accesses the pages field of vm_struct according to the nr_pages field at
>> show_numa_info(). Thus, a null pointer access happens.
>>
>> Patch:
>> This patch sets nr_pages field of vm_struct AFTER the pages allocations
>> finished in __vmalloc_area_node(). So, it can avoid accessing the pages
>> field with unallocated page when show_numa_info() is called.
>
> I think this is still just a workaround to fix up the real bug, and
> that the real bug is that the vm_struct is installed into the vmlist
> *before* it is fully initialised. It's just wrong to insert an object
> into a globally-visible list and to then start populating it! If we
> were instead to fully initialise the vm_struct and *then* insert it
> into vmlist, the bug is fixed.
>
> Also I'd agree with Paul's concern regarding cross-CPU memory ordering.
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-08-20 4:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-19 10:51 [PATCH v2] avoid null pointer access in vm_struct Mitsuo Hayasaka
2011-08-19 18:53 ` Paul E. McKenney
2011-08-19 22:52 ` Andrew Morton
2011-08-20 4:22 ` HAYASAKA Mitsuo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).