]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Jun 2017 12:44:56 +0000 (14:44 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Jun 2017 12:44:56 +0000 (14:44 +0200)
added patches:
rxrpc-fix-several-cases-where-a-padded-len-isn-t-checked-in-ticket-decode.patch

queue-4.4/rxrpc-fix-several-cases-where-a-padded-len-isn-t-checked-in-ticket-decode.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/rxrpc-fix-several-cases-where-a-padded-len-isn-t-checked-in-ticket-decode.patch b/queue-4.4/rxrpc-fix-several-cases-where-a-padded-len-isn-t-checked-in-ticket-decode.patch
new file mode 100644 (file)
index 0000000..3c4c29d
--- /dev/null
@@ -0,0 +1,205 @@
+From 5f2f97656ada8d811d3c1bef503ced266fcd53a0 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@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
+
+From: David Howells <dhowells@redhat.com>
+
+commit 5f2f97656ada8d811d3c1bef503ced266fcd53a0 upstream.
+
+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@360.cn>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Marc Dionne <marc.c.dionne@auristor.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rxrpc/ar-key.c |   64 ++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 34 insertions(+), 30 deletions(-)
+
+--- a/net/rxrpc/ar-key.c
++++ b/net/rxrpc/ar-key.c
+@@ -215,7 +215,7 @@ static int rxrpc_krb5_decode_principal(s
+                                      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 */
+@@ -245,16 +245,16 @@ static int rxrpc_krb5_decode_principal(s
+               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)
+@@ -263,16 +263,16 @@ static int rxrpc_krb5_decode_principal(s
+       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);
+@@ -291,7 +291,7 @@ static int rxrpc_krb5_decode_tagged_data
+                                        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)
+@@ -305,15 +305,17 @@ static int rxrpc_krb5_decode_tagged_data
+       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);
+@@ -385,7 +387,7 @@ static int rxrpc_krb5_decode_ticket(u8 *
+                                   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)
+@@ -397,6 +399,9 @@ static int rxrpc_krb5_decode_ticket(u8 *
+       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);
+@@ -405,9 +410,8 @@ static int rxrpc_krb5_decode_ticket(u8 *
+               *_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;
+@@ -550,7 +554,7 @@ static int rxrpc_preparse_xdr(struct key
+ {
+       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;
+@@ -576,22 +580,21 @@ static int rxrpc_preparse_xdr(struct key
+       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)
+@@ -612,10 +615,11 @@ static int rxrpc_preparse_xdr(struct key
+               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);
index 0434c6e82374615427605fca838f8d860f57715e..7e0cedbbc2db6b0d7434abb55ef83d4503be5e10 100644 (file)
@@ -15,3 +15,4 @@ drm-radeon-add-a-quirk-for-toshiba-satellite-l20-183.patch
 drm-amdgpu-atom-fix-ps-allocation-size-for-enabledisppowergating.patch
 drm-amdgpu-adjust-default-display-clock.patch
 usb-usbip-fix-nonconforming-hub-descriptor.patch
+rxrpc-fix-several-cases-where-a-padded-len-isn-t-checked-in-ticket-decode.patch