diff options
Diffstat (limited to 'setup_arg_pages-diagnose-excessive-argument-size.patch')
-rw-r--r-- | setup_arg_pages-diagnose-excessive-argument-size.patch | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/setup_arg_pages-diagnose-excessive-argument-size.patch b/setup_arg_pages-diagnose-excessive-argument-size.patch new file mode 100644 index 0000000..ead972a --- /dev/null +++ b/setup_arg_pages-diagnose-excessive-argument-size.patch @@ -0,0 +1,42 @@ +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 +--- 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; |