| From: Roland McGrath <roland@redhat.com> |
| Date: Wed, 8 Sep 2010 02:35:49 +0000 (-0700) |
| Subject: setup_arg_pages: diagnose excessive argument size |
| X-Git-Tag: v2.6.36-rc4~14 |
| X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=1b528181b2ffa14721fb28ad1bd539fe1732c583 |
| |
| setup_arg_pages: diagnose excessive argument size |
| |
| 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> |
| |
| |
| diff --git a/fs/exec.c b/fs/exec.c |
| index 2d94552..1b63237 100644 |
| |
| |
| @@ -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; |