From a440c07665d64806a94db1e39ce2dae09d1ff78b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 28 Jan 2009 13:43:50 -0800 Subject: Fix OOPS in mmap_region() when merging adjacent VM_LOCKED file segments This patch differs from the upstream commit de33c8db5910cda599899dd431cc30d7c1018cbf written by Linus, as it aims to only prevent the oops from happening, not attempt to change anything else. The problem was introduced by commit ba470de43188cdbff795b5da43a1474523c6c2fb which added new references to *vma after we've potentially freed it. From: Andrew Morton Reported-by: Maksim Yevmenkin Tested-by: Maksim Yevmenkin Cc: Lee Schermerhorn Cc: Nick Piggin Cc: Andrew Morton Cc: Rik van Riel Cc: Hugh Dickins Cc: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/mmap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 937b44f0aac3..9c3f4f82a46e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1095,6 +1095,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *prev; + struct vm_area_struct *merged_vma; int correct_wcount = 0; int error; struct rb_node **rb_link, *rb_parent; @@ -1207,13 +1208,17 @@ munmap_back: if (vma_wants_writenotify(vma)) vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); - if (file && vma_merge(mm, prev, addr, vma->vm_end, - vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { + merged_vma = NULL; + if (file) + merged_vma = vma_merge(mm, prev, addr, vma->vm_end, + vma->vm_flags, NULL, file, pgoff, vma_policy(vma)); + if (merged_vma) { mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); fput(file); if (vm_flags & VM_EXECUTABLE) removed_exe_file_vma(mm); + vma = merged_vma; } else { vma_link(mm, vma, prev, rb_link, rb_parent); file = vma->vm_file; -- cgit v1.2.3