[linux] 06/06: fs/exec.c: account for argv/envp pointers (CVE-2017-1000365)
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Wed Jul 26 21:37:27 UTC 2017
This is an automated email from the git hooks/post-receive script.
carnil pushed a commit to branch stretch-security
in repository linux.
commit 2e52ae78085fb57003efb5862b550b96ae3853b4
Author: Salvatore Bonaccorso <carnil at debian.org>
Date: Wed Jul 26 23:22:31 2017 +0200
fs/exec.c: account for argv/envp pointers (CVE-2017-1000365)
---
debian/changelog | 1 +
.../fs-exec.c-account-for-argv-envp-pointers.patch | 90 ++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 92 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 08ddef7..cb4d572 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,6 +11,7 @@ linux (4.9.30-2+deb9u3) UNRELEASED; urgency=medium
* drm/virtio: don't leak bo on drm_gem_object_init failure (CVE-2017-10810)
* xen-blkback: don't leak stack data via response ring (CVE-2017-10911)
* mqueue: fix a use-after-free in sys_mq_notify() (CVE-2017-11176)
+ * fs/exec.c: account for argv/envp pointers (CVE-2017-1000365)
-- Salvatore Bonaccorso <carnil at debian.org> Wed, 26 Jul 2017 22:08:32 +0200
diff --git a/debian/patches/bugfix/all/fs-exec.c-account-for-argv-envp-pointers.patch b/debian/patches/bugfix/all/fs-exec.c-account-for-argv-envp-pointers.patch
new file mode 100644
index 0000000..aa15c52
--- /dev/null
+++ b/debian/patches/bugfix/all/fs-exec.c-account-for-argv-envp-pointers.patch
@@ -0,0 +1,90 @@
+From: Kees Cook <keescook at chromium.org>
+Date: Fri, 23 Jun 2017 15:08:57 -0700
+Subject: fs/exec.c: account for argv/envp pointers
+Origin: https://git.kernel.org/linus/98da7d08850fb8bdeb395d6368ed15753304aa0c
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-1000365
+
+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).
+
+[akpm at linux-foundation.org: additional commenting from Kees]
+Fixes: b6a2fea39318 ("mm: variable length argument support")
+Link: http://lkml.kernel.org/r/20170622001720.GA32173@beast
+Signed-off-by: Kees Cook <keescook at chromium.org>
+Acked-by: Rik van Riel <riel at redhat.com>
+Acked-by: Michal Hocko <mhocko at suse.com>
+Cc: Alexander Viro <viro at zeniv.linux.org.uk>
+Cc: Qualys Security Advisory <qsa at qualys.com>
+Cc: <stable at vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+---
+ fs/exec.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 72934df68471..904199086490 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -220,8 +220,26 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+
+ if (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 linux_binprm *bprm, unsigned long pos,
+ * 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)
+--
+2.11.0
+
diff --git a/debian/patches/series b/debian/patches/series
index ea763e7..1711a03 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -130,6 +130,7 @@ bugfix/x86/drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch
bugfix/all/drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
bugfix/all/xen-blkback-don-t-leak-stack-data-via-response-ring.patch
bugfix/all/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch
+bugfix/all/fs-exec.c-account-for-argv-envp-pointers.patch
# Fix exported symbol versions
bugfix/ia64/revert-ia64-move-exports-to-definitions.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git
More information about the Kernel-svn-changes
mailing list