[linux] 01/01: rxrpc: Fix several cases where a padded len isn't checked in ticket decode (CVE-2017-7482)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Thu Jun 29 06:47:03 UTC 2017


This is an automated email from the git hooks/post-receive script.

carnil pushed a commit to branch sid
in repository linux.

commit 3aaf7fba552573596b3f19132745fa7c6ec808ed
Author: Salvatore Bonaccorso <carnil at debian.org>
Date:   Thu Jun 29 08:21:56 2017 +0200

    rxrpc: Fix several cases where a padded len isn't checked in ticket decode (CVE-2017-7482)
---
 debian/changelog                                   |   4 +
 ...everal-cases-where-a-padded-len-isn-t-che.patch | 206 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 3 files changed, 211 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index dd47e69..49b1642 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -79,6 +79,10 @@ linux (4.11.7-1) UNRELEASED; urgency=medium
   [ Vagrant Cascadian ]
   * [arm64] Enable support for Rockchip systems (Closes: #860976).
 
+  [ Salvatore Bonaccorso ]
+  * rxrpc: Fix several cases where a padded len isn't checked in ticket decode
+    (CVE-2017-7482)
+
  -- Ben Hutchings <ben at decadent.org.uk>  Tue, 20 Jun 2017 19:18:44 +0100
 
 linux (4.11.6-1) unstable; urgency=medium
diff --git a/debian/patches/bugfix/all/rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch b/debian/patches/bugfix/all/rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
new file mode 100644
index 0000000..06f79be
--- /dev/null
+++ b/debian/patches/bugfix/all/rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
@@ -0,0 +1,206 @@
+From: David Howells <dhowells at redhat.com>
+Date: Thu, 15 Jun 2017 00:12:24 +0100
+Subject: 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
+Origin: https://git.kernel.org/linus/5f2f97656ada8d811d3c1bef503ced266fcd53a0
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-7482
+
+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>
+---
+ 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 0a4e28477ad9..54369225766e 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/debian/patches/series b/debian/patches/series
index 8fa57a5..61a6e03 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -145,6 +145,7 @@ bugfix/all/tracing-Use-strlcpy-instead-of-strcpy-in-__trace_fin.patch
 bugfix/all/sunrpc-refactor-svc_set_num_threads.patch
 bugfix/all/nfsv4-fix-callback-server-shutdown.patch
 bugfix/all/nfsv4.x-callback-create-the-callback-service-through.patch
+bugfix/all/rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
 
 # Fix exported symbol versions
 bugfix/sparc/revert-sparc-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