]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mm: make stack guard page logic use vm_prev pointer
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Aug 2010 23:49:40 +0000 (16:49 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Aug 2010 23:41:45 +0000 (16:41 -0700)
commit 0e8e50e20c837eeec8323bba7dcd25fe5479194c upstream.

Like the mlock() change previously, this makes the stack guard check
code use vma->vm_prev to see what the mapping below the current stack
is, rather than have to look it up with find_vma().

Also, accept an abutting stack segment, since that happens naturally if
you split the stack with mlock or mprotect.

Tested-by: Ian Campbell <ijc@hellion.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
mm/memory.c

index babb991fb02ba69bdfec04347a14dc2e81d9a836..194dc17560ce3437e5feddd46d032c7ce862ee65 100644 (file)
@@ -2640,11 +2640,18 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
 {
        address &= PAGE_MASK;
        if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
-               address -= PAGE_SIZE;
-               if (find_vma(vma->vm_mm, address) != vma)
-                       return -ENOMEM;
+               struct vm_area_struct *prev = vma->vm_prev;
+
+               /*
+                * Is there a mapping abutting this one below?
+                *
+                * That's only ok if it's the same stack mapping
+                * that has gotten split..
+                */
+               if (prev && prev->vm_end == address)
+                       return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
 
-               expand_stack(vma, address);
+               expand_stack(vma, address - PAGE_SIZE);
        }
        return 0;
 }