summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-09-07 19:35:49 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-28 21:44:16 -0700
commit8816b5d01705e2c5c32bbf9e39e9aebad10b5dca (patch)
tree45e42e7760606c1f94a32dcde543d0e2e490779f
parentc6e6bb4981ea1c05304f18dc618f0b08f9c965b4 (diff)
setup_arg_pages: diagnose excessive argument size
commit 1b528181b2ffa14721fb28ad1bd539fe1732c583 upstream. The CONFIG_STACK_GROWSDOWN variant of setup_arg_pages() does not check the size of the argument/environment area on the stack. When it is unworkably large, shift_arg_pages() hits its BUG_ON. This is exploitable with a very large RLIMIT_STACK limit, to create a crash pretty easily. Check that the initial stack is not too large to make it possible to map in any executable. We're not checking that the actual executable (or intepreter, for binfmt_elf) will fit. So those mappings might clobber part of the initial stack mapping. But that is just userland lossage that userland made happen, not a kernel problem. Signed-off-by: Roland McGrath <roland@redhat.com> Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Chuck Ebbert <cebbert@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/exec.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 56da15f6d771..ca3d4a61fe23 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -594,6 +594,11 @@ int setup_arg_pages(struct linux_binprm *bprm,
#else
stack_top = arch_align_stack(stack_top);
stack_top = PAGE_ALIGN(stack_top);
+
+ if (unlikely(stack_top < mmap_min_addr) ||
+ unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
+ return -ENOMEM;
+
stack_shift = vma->vm_end - stack_top;
bprm->p -= stack_shift;