diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-20 16:49:40 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-26 16:45:56 -0700 |
commit | 6bed99917d414371cd5342158b6ed514ee8fee45 (patch) | |
tree | d755f62f61398d939ab216e25943daf706bb1b6e /mm | |
parent | e89cfc48a21fa83088e083fe6341ff803ab32f8e (diff) | |
download | kernel-crypto-6bed99917d414371cd5342158b6ed514ee8fee45.tar.gz kernel-crypto-6bed99917d414371cd5342158b6ed514ee8fee45.tar.xz kernel-crypto-6bed99917d414371cd5342158b6ed514ee8fee45.zip |
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.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c index 307bf77fc44..53cf85d4444 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; } |