| From 0e8e50e20c837eeec8323bba7dcd25fe5479194c Mon Sep 17 00:00:00 2001 |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| Date: Fri, 20 Aug 2010 16:49:40 -0700 |
| Subject: mm: make stack guard page logic use vm_prev pointer |
| |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| 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 | 15 +++++++++++---- |
| 1 file changed, 11 insertions(+), 4 deletions(-) |
| |
| --- a/mm/memory.c |
| +++ b/mm/memory.c |
| @@ -2761,11 +2761,18 @@ static inline int check_stack_guard_page |
| { |
| 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; |
| |
| - expand_stack(vma, address); |
| + /* |
| + * 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 - PAGE_SIZE); |
| } |
| return 0; |
| } |