Patch "fs/exec.c: account for argv/envp pointers" has been added to the 4.11-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
fs/exec.c: account for argv/envp pointers
to the 4.11-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
fs-exec.c-account-for-argv-envp-pointers.patch
and it can be found in the queue-4.11 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
98da7d08850fb8bdeb395d6368ed15753304aa0cMon Sep 17 00:00:00 2001
From: Kees Cook <[email protected]>
Date: Fri, 23 Jun 2017 15:08:57 -0700
Subject: fs/exec.c: account for argv/envp pointers
From: Kees Cook <[email protected]>
commit 98da7d08850fb8bdeb395d6368ed15753304aa0c upstream.
When limiting the argv/envp strings during exec to 1/4 of the stack limit, the storage of the pointers to the strings was not included. This means that an exec with huge numbers of tiny strings could eat 1/4 of the stack limit in strings and then additional space would be later used by the pointers to the strings.
For example, on 32-bit with a 8MB stack rlimit, an exec with 1677721 single-byte strings would consume less than 2MB of stack, the max (8MB /
4) amount allowed, but the pointers to the strings would consume the remaining additional stack space (1677721 * 4 == 6710884).
The result (1677721 + 6710884 == 8388605) would exhaust stack space entirely. Controlling this stack exhaustion could result in pathological behavior in setuid binaries (CVE-2017-1000365).
--- fs/exec.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
fs/exec.c +24 -4
@@ -220,8 +220,26 @@ static struct page *get_arg_page(structif (write) {unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; +unsigned long ptr_size;struct rlimit *rlim; +/* +* Since the stack will hold pointers to the strings, we +* must account for them as well. +* +* The size calculation is the entire vma while each arg page is +* built, so each time we get here it's calculating how far it +* is currently (rather than each call being just the newly +* added size from the arg page). As a result, we need to +* always add the entire size of the pointers, so that on the +* last call to get_arg_page() we'll actually have the entire +* correct size. +*/ + ptr_size = (bprm->argc + bprm->envc) *sizeof (void *); +if (ptr_size >ULONG_MAX - size) + goto fail; + size += ptr_size; +acct_arg_size (bprm, size /PAGE_SIZE );/*
@@ -239,13 +257,15 @@ static struct page *get_arg_page(struct* to work from. */ rlim = current->signal->rlim; -if (size >ACCESS_ONCE (rlim[RLIMIT_STACK ].rlim_cur) /4 ) { -put_page (page); -return NULL ; - } +if (size >READ_ONCE (rlim[RLIMIT_STACK ].rlim_cur) /4 ) + goto fail; }return page; + +fail: +put_page (page); +return NULL ; }static void put_arg_page (struct page *page)
Patches currently in stable-queue which might be from [email protected] are
queue-4.11/fs-exec.c-account-for-argv-envp-pointers.patch