mm: do not grow the stack vma just because of an overrun on preceding vma
[pandora-kernel.git] / mm / mmap.c
index 94f4e34..e949a20 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1802,9 +1802,28 @@ int expand_downwards(struct vm_area_struct *vma,
        return error;
 }
 
+/*
+ * Note how expand_stack() refuses to expand the stack all the way to
+ * abut the next virtual mapping, *unless* that mapping itself is also
+ * a stack mapping. We want to leave room for a guard page, after all
+ * (the guard page itself is not added here, that is done by the
+ * actual page faulting logic)
+ *
+ * This matches the behavior of the guard page logic (see mm/memory.c:
+ * check_stack_guard_page()), which only allows the guard page to be
+ * removed under these circumstances.
+ */
 #ifdef CONFIG_STACK_GROWSUP
 int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
+       struct vm_area_struct *next;
+
+       address &= PAGE_MASK;
+       next = vma->vm_next;
+       if (next && next->vm_start == address + PAGE_SIZE) {
+               if (!(next->vm_flags & VM_GROWSUP))
+                       return -ENOMEM;
+       }
        return expand_upwards(vma, address);
 }
 
@@ -1827,6 +1846,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
 #else
 int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
+       struct vm_area_struct *prev;
+
+       address &= PAGE_MASK;
+       prev = vma->vm_prev;
+       if (prev && prev->vm_end == address) {
+               if (!(prev->vm_flags & VM_GROWSDOWN))
+                       return -ENOMEM;
+       }
        return expand_downwards(vma, address);
 }