| From b25291aea8e7abe48d387e1d76d89e44d1c78175 Mon Sep 17 00:00:00 2001 |
| From: Dave Hansen <dave@linux.vnet.ibm.com> |
| Date: Wed, 30 May 2012 07:51:07 -0700 |
| Subject: [PATCH] mm: fix vma_resv_map() NULL pointer |
| |
| commit 4523e1458566a0e8ecfaff90f380dd23acc44d27 upstream. |
| |
| hugetlb_reserve_pages() can be used for either normal file-backed |
| hugetlbfs mappings, or MAP_HUGETLB. In the MAP_HUGETLB, semi-anonymous |
| mode, there is not a VMA around. The new call to resv_map_put() assumed |
| that there was, and resulted in a NULL pointer dereference: |
| |
| BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 |
| IP: vma_resv_map+0x9/0x30 |
| PGD 141453067 PUD 1421e1067 PMD 0 |
| Oops: 0000 [#1] PREEMPT SMP |
| ... |
| Pid: 14006, comm: trinity-child6 Not tainted 3.4.0+ #36 |
| RIP: vma_resv_map+0x9/0x30 |
| ... |
| Process trinity-child6 (pid: 14006, threadinfo ffff8801414e0000, task ffff8801414f26b0) |
| Call Trace: |
| resv_map_put+0xe/0x40 |
| hugetlb_reserve_pages+0xa6/0x1d0 |
| hugetlb_file_setup+0x102/0x2c0 |
| newseg+0x115/0x360 |
| ipcget+0x1ce/0x310 |
| sys_shmget+0x5a/0x60 |
| system_call_fastpath+0x16/0x1b |
| |
| This was reported by Dave Jones, but was reproducible with the |
| libhugetlbfs test cases, so shame on me for not running them in the |
| first place. |
| |
| With this, the oops is gone, and the output of libhugetlbfs's |
| run_tests.py is identical to plain 3.4 again. |
| |
| [ Marked for stable, since this was introduced by commit c50ac050811d |
| ("hugetlb: fix resv_map leak in error path") which was also marked for |
| stable ] |
| |
| Reported-by: Dave Jones <davej@redhat.com> |
| Cc: Mel Gorman <mel@csn.ul.ie> |
| Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> |
| Cc: Christoph Lameter <cl@linux.com> |
| Cc: Andrea Arcangeli <aarcange@redhat.com> |
| Cc: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
| index f7b8054..c80dd85 100644 |
| --- a/mm/hugetlb.c |
| +++ b/mm/hugetlb.c |
| @@ -2789,7 +2789,8 @@ int hugetlb_reserve_pages(struct inode *inode, |
| region_add(&inode->i_mapping->private_list, from, to); |
| return 0; |
| out_err: |
| - resv_map_put(vma); |
| + if (vma) |
| + resv_map_put(vma); |
| return ret; |
| } |
| |
| -- |
| 1.8.1.2 |
| |