diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-20 19:49:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-21 11:50:00 -0400 |
commit | 0e8e50e20c837eeec8323bba7dcd25fe5479194c (patch) | |
tree | 12c7ec767a4a8508be33442c6fb55c28a26c94cd | |
parent | 7798330ac8114c731cfab83e634c6ecedaa233d7 (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.c | 15 |
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 | } |