aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-20 19:49:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-21 11:50:00 -0400
commit0e8e50e20c837eeec8323bba7dcd25fe5479194c (patch)
tree12c7ec767a4a8508be33442c6fb55c28a26c94cd
parent7798330ac8114c731cfab83e634c6ecedaa233d7 (diff)
mm: make stack guard page logic use vm_prev pointer
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>
-rw-r--r--mm/memory.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c
index b6e5fd23cc5a..2ed2267439df 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2770,11 +2770,18 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo
2770{ 2770{
2771 address &= PAGE_MASK; 2771 address &= PAGE_MASK;
2772 if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { 2772 if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
2773 address -= PAGE_SIZE; 2773 struct vm_area_struct *prev = vma->vm_prev;
2774 if (find_vma(vma->vm_mm, address) != vma) 2774
2775 return -ENOMEM; 2775 /*
2776 * Is there a mapping abutting this one below?
2777 *
2778 * That's only ok if it's the same stack mapping
2779 * that has gotten split..
2780 */
2781 if (prev && prev->vm_end == address)
2782 return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
2776 2783
2777 expand_stack(vma, address); 2784 expand_stack(vma, address - PAGE_SIZE);
2778 } 2785 }
2779 return 0; 2786 return 0;
2780} 2787}