Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1183

kernel-2.6.18-238.el5.src.rpm

From: Oleg Nesterov <oleg@redhat.com>
Date: Sun, 28 Nov 2010 20:57:23 -0500
Subject: [fs] setup_arg_pages: diagnose excessive argument size
Message-id: <20101128205723.GA26052@redhat.com>
Patchwork-id: 29646
O-Subject: [RHEL5.6 PATCH] bz645227: setup_arg_pages: diagnose excessive
	argument size
Bugzilla: 645227
RH-Acked-by: Amerigo Wang <amwang@redhat.com>
RH-Acked-by: Danny Feng <dfeng@redhat.com>

https://bugzilla.redhat.com/show_bug.cgi?id=645227

Upstream commit 1b528181b2ffa14721fb28ad1bd539fe1732c583
Author: Roland McGrath <roland@redhat.com>
Date:   Tue Sep 7 19:35:49 2010 -0700

    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>

Signed-off-by: Oleg Nesterov <oleg@redhat.com>

diff --git a/fs/exec.c b/fs/exec.c
index 170a093..0881cc4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -620,6 +620,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;