aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2017-06-19 11:34:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-06-21 14:07:18 -0400
commitbd726c90b6b8ce87602208701b208a208e6d5600 (patch)
tree4108143f648b9f0bffed509c0afffbe933036f2b
parentf4cb767d76cf7ee72f97dd76f6cfa6c76a5edc89 (diff)
Allow stack to grow up to address space limit
Fix expand_upwards() on architectures with an upward-growing stack (parisc, metag and partly IA-64) to allow the stack to reliably grow exactly up to the address space limit given by TASK_SIZE. Signed-off-by: Helge Deller <deller@gmx.de> Acked-by: Hugh Dickins <hughd@google.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/mmap.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 290b77d9a01e..a5e3dcd75e79 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2230,16 +2230,19 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
2230 if (!(vma->vm_flags & VM_GROWSUP)) 2230 if (!(vma->vm_flags & VM_GROWSUP))
2231 return -EFAULT; 2231 return -EFAULT;
2232 2232
2233 /* Guard against wrapping around to address 0. */ 2233 /* Guard against exceeding limits of the address space. */
2234 address &= PAGE_MASK; 2234 address &= PAGE_MASK;
2235 address += PAGE_SIZE; 2235 if (address >= TASK_SIZE)
2236 if (!address)
2237 return -ENOMEM; 2236 return -ENOMEM;
2237 address += PAGE_SIZE;
2238 2238
2239 /* Enforce stack_guard_gap */ 2239 /* Enforce stack_guard_gap */
2240 gap_addr = address + stack_guard_gap; 2240 gap_addr = address + stack_guard_gap;
2241 if (gap_addr < address) 2241
2242 return -ENOMEM; 2242 /* Guard against overflow */
2243 if (gap_addr < address || gap_addr > TASK_SIZE)
2244 gap_addr = TASK_SIZE;
2245
2243 next = vma->vm_next; 2246 next = vma->vm_next;
2244 if (next && next->vm_start < gap_addr) { 2247 if (next && next->vm_start < gap_addr) {
2245 if (!(next->vm_flags & VM_GROWSUP)) 2248 if (!(next->vm_flags & VM_GROWSUP))