[pve-devel] [PATCH kernel] add CVE fixes

Thomas Lamprecht t.lamprecht at proxmox.com
Tue Jul 18 14:53:59 CEST 2017


CVE-2017-1000364 (rather bugfix for the original CVE fix):
 * mm/mmap.c: expand_downwards: don't require the gap if !vm_prev
 * mm/mmap.c: do not blow on PROT_NONE MAP_FIXED holes in the stack

CVE-2017-1000365: fs/exec.c: account for argv/envp pointers

CVE-2017-10810: drm/virtio: don't leak bo on drm_gem_object_init
 failure

CVE-2017-7482: rxrpc: Fix several cases where a padded len isn't
 checked in ticket decode

Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---

pulled from master-next, CVE-2017-100036? gets some fixes for regressions
caused by the larger stack guard gap approach.
CVE-2017-10810 and CVE-2017-7482 are new.

 ...o-not-blow-on-PROT_NONE-MAP_FIXED-holes-i.patch |  72 +++++++
 ...xpand_downwards-don-t-require-the-gap-if-.patch |  71 +++++++
 ...-fs-exec.c-account-for-argv-envp-pointers.patch |  99 ++++++++++
 ...don-t-leak-bo-on-drm_gem_object_init-fail.patch |  43 +++++
 ...everal-cases-where-a-padded-len-isn-t-che.patch | 215 +++++++++++++++++++++
 Makefile                                           |   5 +
 6 files changed, 505 insertions(+)
 create mode 100644 CVE-2017-1000364-mm-mmap.c-do-not-blow-on-PROT_NONE-MAP_FIXED-holes-i.patch
 create mode 100644 CVE-2017-1000364-mm-mmap.c-expand_downwards-don-t-require-the-gap-if-.patch
 create mode 100644 CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch
 create mode 100644 CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
 create mode 100644 CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch

diff --git a/CVE-2017-1000364-mm-mmap.c-do-not-blow-on-PROT_NONE-MAP_FIXED-holes-i.patch b/CVE-2017-1000364-mm-mmap.c-do-not-blow-on-PROT_NONE-MAP_FIXED-holes-i.patch
new file mode 100644
index 0000000..75b4522
--- /dev/null
+++ b/CVE-2017-1000364-mm-mmap.c-do-not-blow-on-PROT_NONE-MAP_FIXED-holes-i.patch
@@ -0,0 +1,72 @@
+From 3e4f09eef73ad12d4876e24daf52a0dc0891d7da Mon Sep 17 00:00:00 2001
+From: Michal Hocko <mhocko at suse.com>
+Date: Mon, 17 Jul 2017 14:53:28 +0200
+Subject: [PATCH 1/2] mm/mmap.c: do not blow on PROT_NONE MAP_FIXED holes in
+ the stack
+
+Commit 1be7107fbe18 ("mm: larger stack guard gap, between vmas") has
+introduced a regression in some rust and Java environments which are
+trying to implement their own stack guard page.  They are punching a new
+MAP_FIXED mapping inside the existing stack Vma.
+
+This will confuse expand_{downwards,upwards} into thinking that the
+stack expansion would in fact get us too close to an existing non-stack
+vma which is a correct behavior wrt safety.  It is a real regression on
+the other hand.
+
+Let's work around the problem by considering PROT_NONE mapping as a part
+of the stack.  This is a gros hack but overflowing to such a mapping
+would trap anyway an we only can hope that usespace knows what it is
+doing and handle it propely.
+
+Fixes: 1be7107fbe18 ("mm: larger stack guard gap, between vmas")
+Link: http://lkml.kernel.org/r/20170705182849.GA18027@dhcp22.suse.cz
+Signed-off-by: Michal Hocko <mhocko at suse.com>
+Debugged-by: Vlastimil Babka <vbabka at suse.cz>
+Cc: Ben Hutchings <ben at decadent.org.uk>
+Cc: Willy Tarreau <w at 1wt.eu>
+Cc: Oleg Nesterov <oleg at redhat.com>
+Cc: Rik van Riel <riel at redhat.com>
+Cc: Hugh Dickins <hughd at google.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+CVE-2017-1000364
+
+(cherry picked from commit 561b5e0709e4a248c67d024d4d94b6e31e3edf2f)
+Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
+Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
+Acked-by: Kamal Mostafa <kamal at canonical.com>
+Signed-off-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
+Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
+---
+ mm/mmap.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index ef78a5ca5599..9fabd8c82f38 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2240,7 +2240,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
+ 		gap_addr = TASK_SIZE;
+ 
+ 	next = vma->vm_next;
+-	if (next && next->vm_start < gap_addr) {
++	if (next && next->vm_start < gap_addr &&
++			(next->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) {
+ 		if (!(next->vm_flags & VM_GROWSUP))
+ 			return -ENOMEM;
+ 		/* Check that both stack segments have the same anon_vma? */
+@@ -2324,7 +2325,8 @@ int expand_downwards(struct vm_area_struct *vma,
+ 	if (gap_addr > address)
+ 		return -ENOMEM;
+ 	prev = vma->vm_prev;
+-	if (prev && prev->vm_end > gap_addr) {
++	if (prev && prev->vm_end > gap_addr &&
++			(prev->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) {
+ 		if (!(prev->vm_flags & VM_GROWSDOWN))
+ 			return -ENOMEM;
+ 		/* Check that both stack segments have the same anon_vma? */
+-- 
+2.11.0
+
diff --git a/CVE-2017-1000364-mm-mmap.c-expand_downwards-don-t-require-the-gap-if-.patch b/CVE-2017-1000364-mm-mmap.c-expand_downwards-don-t-require-the-gap-if-.patch
new file mode 100644
index 0000000..6fa4bfb
--- /dev/null
+++ b/CVE-2017-1000364-mm-mmap.c-expand_downwards-don-t-require-the-gap-if-.patch
@@ -0,0 +1,71 @@
+From aea792ba99ba73a6b0c4e5aea3b4b6b3f9d821f6 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg at redhat.com>
+Date: Mon, 17 Jul 2017 14:53:29 +0200
+Subject: [PATCH 2/2] mm/mmap.c: expand_downwards: don't require the gap if
+ !vm_prev
+
+expand_stack(vma) fails if address < stack_guard_gap even if there is no
+vma->vm_prev.  I don't think this makes sense, and we didn't do this
+before the recent commit 1be7107fbe18 ("mm: larger stack guard gap,
+between vmas").
+
+We do not need a gap in this case, any address is fine as long as
+security_mmap_addr() doesn't object.
+
+This also simplifies the code, we know that address >= prev->vm_end and
+thus underflow is not possible.
+
+Link: http://lkml.kernel.org/r/20170628175258.GA24881@redhat.com
+Signed-off-by: Oleg Nesterov <oleg at redhat.com>
+Acked-by: Michal Hocko <mhocko at suse.com>
+Cc: Hugh Dickins <hughd at google.com>
+Cc: Larry Woodman <lwoodman at redhat.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+CVE-2017-1000364
+
+(cherry picked from commit 32e4e6d5cbb0c0e427391635991fe65e17797af8)
+Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
+Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
+Acked-by: Kamal Mostafa <kamal at canonical.com>
+Signed-off-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
+Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
+---
+ mm/mmap.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 9fabd8c82f38..09c728a1eeee 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2312,7 +2312,6 @@ int expand_downwards(struct vm_area_struct *vma,
+ {
+ 	struct mm_struct *mm = vma->vm_mm;
+ 	struct vm_area_struct *prev;
+-	unsigned long gap_addr;
+ 	int error;
+ 
+ 	address &= PAGE_MASK;
+@@ -2321,15 +2320,12 @@ int expand_downwards(struct vm_area_struct *vma,
+ 		return error;
+ 
+ 	/* Enforce stack_guard_gap */
+-	gap_addr = address - stack_guard_gap;
+-	if (gap_addr > address)
+-		return -ENOMEM;
+ 	prev = vma->vm_prev;
+-	if (prev && prev->vm_end > gap_addr &&
++	/* Check that both stack segments have the same anon_vma? */
++	if (prev && !(prev->vm_flags & VM_GROWSDOWN) &&
+ 			(prev->vm_flags & (VM_WRITE|VM_READ|VM_EXEC))) {
+-		if (!(prev->vm_flags & VM_GROWSDOWN))
++		if (address - prev->vm_end < stack_guard_gap)
+ 			return -ENOMEM;
+-		/* Check that both stack segments have the same anon_vma? */
+ 	}
+ 
+ 	/* We must make sure the anon_vma is allocated. */
+-- 
+2.11.0
+
diff --git a/CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch b/CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch
new file mode 100644
index 0000000..e85ea99
--- /dev/null
+++ b/CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch
@@ -0,0 +1,99 @@
+From 6b44f156198491839655077fc7f3a469c67e1f8d Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook at chromium.org>
+Date: Wed, 12 Jul 2017 15:30:39 +0200
+Subject: [PATCH 2/3] fs/exec.c: account for argv/envp pointers
+
+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>
+
+CVE-2017-1000365
+
+(cherry-picked from commit 98da7d08850fb8bdeb395d6368ed15753304aa0c)
+Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
+Acked-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
+Acked-by: Seth Forshee <seth.forshee at canonical.com>
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
+
+Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
+---
+ fs/exec.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/fs/exec.c b/fs/exec.c
+index 9fb90c37c37f..8cf76e2a0b83 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -225,8 +225,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);
+ 
+ 		/*
+@@ -244,13 +262,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/CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch b/CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
new file mode 100644
index 0000000..8065b6e
--- /dev/null
+++ b/CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
@@ -0,0 +1,43 @@
+From de1c3d4474562e9d9dc9952f9283f07d8d58ef98 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Wed, 12 Jul 2017 12:35:52 +0200
+Subject: [PATCH 1/3] drm/virtio: don't leak bo on drm_gem_object_init failure
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reported-by: 李强 <liqiang6-s at 360.cn>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20170406155941.458-1-kraxel@redhat.com
+
+CVE-2017-10810
+
+(cherry picked from commit 385aee965b4e4c36551c362a334378d2985b722a)
+Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
+Acked-by: Seth Forshee <seth.forshee at canonical.com>
+Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
+Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
+---
+ drivers/gpu/drm/virtio/virtgpu_object.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index 1483daebe057..6f66b7347cd0 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -81,8 +81,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
+ 		return -ENOMEM;
+ 	size = roundup(size, PAGE_SIZE);
+ 	ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size);
+-	if (ret != 0)
++	if (ret != 0) {
++		kfree(bo);
+ 		return ret;
++	}
+ 	bo->dumb = false;
+ 	virtio_gpu_init_ttm_placement(bo, pinned);
+ 
+-- 
+2.11.0
+
diff --git a/CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch b/CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
new file mode 100644
index 0000000..937d6a6
--- /dev/null
+++ b/CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
@@ -0,0 +1,215 @@
+From 453b5039843f7dac534ee23af6b34c2d0a116416 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Wed, 12 Jul 2017 16:30:25 +0200
+Subject: [PATCH 3/3] rxrpc: Fix several cases where a padded len isn't checked
+ in ticket decode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes CVE-2017-7482.
+
+When a kerberos 5 ticket is being decoded so that it can be loaded into an
+rxrpc-type key, there are several places in which the length of a
+variable-length field is checked to make sure that it's not going to
+overrun the available data - but the data is padded to the nearest
+four-byte boundary and the code doesn't check for this extra.  This could
+lead to the size-remaining variable wrapping and the data pointer going
+over the end of the buffer.
+
+Fix this by making the various variable-length data checks use the padded
+length.
+
+Reported-by: 石磊 <shilei-c at 360.cn>
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Marc Dionne <marc.c.dionne at auristor.com>
+Reviewed-by: Dan Carpenter <dan.carpenter at oracle.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+
+CVE-2017-7482
+
+(cherry-picked from commit 5f2f97656ada8d811d3c1bef503ced266fcd53a0)
+Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
+Acked-by: Seth Forshee <seth.forshee at canonical.com>
+Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
+
+Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
+---
+ net/rxrpc/key.c | 64 ++++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 34 insertions(+), 30 deletions(-)
+
+diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
+index 18c737a61d80..7fc340726d03 100644
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -217,7 +217,7 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
+ 				       unsigned int *_toklen)
+ {
+ 	const __be32 *xdr = *_xdr;
+-	unsigned int toklen = *_toklen, n_parts, loop, tmp;
++	unsigned int toklen = *_toklen, n_parts, loop, tmp, paddedlen;
+ 
+ 	/* there must be at least one name, and at least #names+1 length
+ 	 * words */
+@@ -247,16 +247,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
+ 		toklen -= 4;
+ 		if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX)
+ 			return -EINVAL;
+-		if (tmp > toklen)
++		paddedlen = (tmp + 3) & ~3;
++		if (paddedlen > toklen)
+ 			return -EINVAL;
+ 		princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL);
+ 		if (!princ->name_parts[loop])
+ 			return -ENOMEM;
+ 		memcpy(princ->name_parts[loop], xdr, tmp);
+ 		princ->name_parts[loop][tmp] = 0;
+-		tmp = (tmp + 3) & ~3;
+-		toklen -= tmp;
+-		xdr += tmp >> 2;
++		toklen -= paddedlen;
++		xdr += paddedlen >> 2;
+ 	}
+ 
+ 	if (toklen < 4)
+@@ -265,16 +265,16 @@ static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
+ 	toklen -= 4;
+ 	if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX)
+ 		return -EINVAL;
+-	if (tmp > toklen)
++	paddedlen = (tmp + 3) & ~3;
++	if (paddedlen > toklen)
+ 		return -EINVAL;
+ 	princ->realm = kmalloc(tmp + 1, GFP_KERNEL);
+ 	if (!princ->realm)
+ 		return -ENOMEM;
+ 	memcpy(princ->realm, xdr, tmp);
+ 	princ->realm[tmp] = 0;
+-	tmp = (tmp + 3) & ~3;
+-	toklen -= tmp;
+-	xdr += tmp >> 2;
++	toklen -= paddedlen;
++	xdr += paddedlen >> 2;
+ 
+ 	_debug("%s/...@%s", princ->name_parts[0], princ->realm);
+ 
+@@ -293,7 +293,7 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
+ 					 unsigned int *_toklen)
+ {
+ 	const __be32 *xdr = *_xdr;
+-	unsigned int toklen = *_toklen, len;
++	unsigned int toklen = *_toklen, len, paddedlen;
+ 
+ 	/* there must be at least one tag and one length word */
+ 	if (toklen <= 8)
+@@ -307,15 +307,17 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
+ 	toklen -= 8;
+ 	if (len > max_data_size)
+ 		return -EINVAL;
++	paddedlen = (len + 3) & ~3;
++	if (paddedlen > toklen)
++		return -EINVAL;
+ 	td->data_len = len;
+ 
+ 	if (len > 0) {
+ 		td->data = kmemdup(xdr, len, GFP_KERNEL);
+ 		if (!td->data)
+ 			return -ENOMEM;
+-		len = (len + 3) & ~3;
+-		toklen -= len;
+-		xdr += len >> 2;
++		toklen -= paddedlen;
++		xdr += paddedlen >> 2;
+ 	}
+ 
+ 	_debug("tag %x len %x", td->tag, td->data_len);
+@@ -387,7 +389,7 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
+ 				    const __be32 **_xdr, unsigned int *_toklen)
+ {
+ 	const __be32 *xdr = *_xdr;
+-	unsigned int toklen = *_toklen, len;
++	unsigned int toklen = *_toklen, len, paddedlen;
+ 
+ 	/* there must be at least one length word */
+ 	if (toklen <= 4)
+@@ -399,6 +401,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
+ 	toklen -= 4;
+ 	if (len > AFSTOKEN_K5_TIX_MAX)
+ 		return -EINVAL;
++	paddedlen = (len + 3) & ~3;
++	if (paddedlen > toklen)
++		return -EINVAL;
+ 	*_tktlen = len;
+ 
+ 	_debug("ticket len %u", len);
+@@ -407,9 +412,8 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
+ 		*_ticket = kmemdup(xdr, len, GFP_KERNEL);
+ 		if (!*_ticket)
+ 			return -ENOMEM;
+-		len = (len + 3) & ~3;
+-		toklen -= len;
+-		xdr += len >> 2;
++		toklen -= paddedlen;
++		xdr += paddedlen >> 2;
+ 	}
+ 
+ 	*_xdr = xdr;
+@@ -552,7 +556,7 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
+ {
+ 	const __be32 *xdr = prep->data, *token;
+ 	const char *cp;
+-	unsigned int len, tmp, loop, ntoken, toklen, sec_ix;
++	unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
+ 	size_t datalen = prep->datalen;
+ 	int ret;
+ 
+@@ -578,22 +582,21 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
+ 	if (len < 1 || len > AFSTOKEN_CELL_MAX)
+ 		goto not_xdr;
+ 	datalen -= 4;
+-	tmp = (len + 3) & ~3;
+-	if (tmp > datalen)
++	paddedlen = (len + 3) & ~3;
++	if (paddedlen > datalen)
+ 		goto not_xdr;
+ 
+ 	cp = (const char *) xdr;
+ 	for (loop = 0; loop < len; loop++)
+ 		if (!isprint(cp[loop]))
+ 			goto not_xdr;
+-	if (len < tmp)
+-		for (; loop < tmp; loop++)
+-			if (cp[loop])
+-				goto not_xdr;
++	for (; loop < paddedlen; loop++)
++		if (cp[loop])
++			goto not_xdr;
+ 	_debug("cellname: [%u/%u] '%*.*s'",
+-	       len, tmp, len, len, (const char *) xdr);
+-	datalen -= tmp;
+-	xdr += tmp >> 2;
++	       len, paddedlen, len, len, (const char *) xdr);
++	datalen -= paddedlen;
++	xdr += paddedlen >> 2;
+ 
+ 	/* get the token count */
+ 	if (datalen < 12)
+@@ -614,10 +617,11 @@ static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
+ 		sec_ix = ntohl(*xdr);
+ 		datalen -= 4;
+ 		_debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
+-		if (toklen < 20 || toklen > datalen)
++		paddedlen = (toklen + 3) & ~3;
++		if (toklen < 20 || toklen > datalen || paddedlen > datalen)
+ 			goto not_xdr;
+-		datalen -= (toklen + 3) & ~3;
+-		xdr += (toklen + 3) >> 2;
++		datalen -= paddedlen;
++		xdr += paddedlen >> 2;
+ 
+ 	} while (--loop > 0);
+ 
+-- 
+2.11.0
+
diff --git a/Makefile b/Makefile
index 85dc178..c961e42 100644
--- a/Makefile
+++ b/Makefile
@@ -224,6 +224,11 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNEL_SRC_SUBMODULE} | submodules
 	cd ${KERNEL_SRC}; patch -p1 <  ../CVE-2017-1000380-ALSA-timer-Fix-race-between-read-and-ioctl.patch
 	cd ${KERNEL_SRC}; patch -p1 <  ../CVE-2017-7346-drm-vmwgfx-limit-the-number-of-mip-levels-in-vmw_gb_.patch
 	cd ${KERNEL_SRC}; patch -p1 <  ../CVE-2017-9605-drm-vmwgfx-Make-sure-backup_handle-is-always-valid.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000364-mm-mmap.c-do-not-blow-on-PROT_NONE-MAP_FIXED-holes-i.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000364-mm-mmap.c-expand_downwards-don-t-require-the-gap-if-.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
 	sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
 	touch $@
 
-- 
2.11.0





More information about the pve-devel mailing list