summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-20 16:49:40 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-26 16:43:39 -0700
commit7ddb5ec3fdd06d769f58a4d68fa4c3f7de26f2fb (patch)
tree5225a3368c80308676aed512c2d81460e7b7192d /mm
parent259756fcc66e2d6dd732c0b4ff99f825e69b3ba2 (diff)
mm: make stack guard page logic use vm_prev pointer
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>
Diffstat (limited to 'mm')
-rw-r--r--mm/memory.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c
index e48eb86cb6fc..47fb0a0d349d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2761,11 +2761,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;
}