Patchwork [3/6] mm: make stack guard page logic use vm_prev pointer

login
register
mail settings
Submitter Paolo Pisati
Date Nov. 24, 2011, 10:07 a.m.
Message ID <1322129246-5397-4-git-send-email-paolo.pisati@canonical.com>
Download mbox | patch
Permalink /patch/127466/
State New
Headers show

Comments

Paolo Pisati - Nov. 24, 2011, 10:07 a.m.
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>
(cherry picked from commit 6bed99917d414371cd5342158b6ed514ee8fee45)

BugLink: http://launchpad.net/bugs/893190

Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
---
 mm/memory.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

Patch

diff --git a/mm/memory.c b/mm/memory.c
index 4122947..a53d832 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
 {
 	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;
 }