]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Feb 2018 19:40:38 +0000 (20:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Feb 2018 19:40:38 +0000 (20:40 +0100)
added patches:
asn.1-fix-out-of-bounds-read-when-parsing-indefinite-length-item.patch

queue-3.18/asn.1-fix-out-of-bounds-read-when-parsing-indefinite-length-item.patch [new file with mode: 0644]
queue-3.18/netfilter-drop-outermost-socket-lock-in-getsockopt.patch
queue-3.18/series

diff --git a/queue-3.18/asn.1-fix-out-of-bounds-read-when-parsing-indefinite-length-item.patch b/queue-3.18/asn.1-fix-out-of-bounds-read-when-parsing-indefinite-length-item.patch
new file mode 100644 (file)
index 0000000..8fe0e57
--- /dev/null
@@ -0,0 +1,134 @@
+From ebiggers3@gmail.com  Mon Feb 26 20:38:26 2018
+From: Eric Biggers <ebiggers3@gmail.com>
+Date: Mon, 26 Feb 2018 10:43:09 -0800
+Subject: ASN.1: fix out-of-bounds read when parsing indefinite length item
+To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: keyrings@vger.kernel.org, Alexander Potapenko <glider@google.com>, Eric Biggers <ebiggers@google.com>, David Howells <dhowells@redhat.com>
+Message-ID: <20180226184309.228964-1-ebiggers3@gmail.com>
+
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit e0058f3a874ebb48b25be7ff79bc3b4e59929f90 upstream.
+
+In asn1_ber_decoder(), indefinitely-sized ASN.1 items were being passed
+to the action functions before their lengths had been computed, using
+the bogus length of 0x80 (ASN1_INDEFINITE_LENGTH).  This resulted in
+reading data past the end of the input buffer, when given a specially
+crafted message.
+
+Fix it by rearranging the code so that the indefinite length is resolved
+before the action is called.
+
+This bug was originally found by fuzzing the X.509 parser in userspace
+using libFuzzer from the LLVM project.
+
+KASAN report (cleaned up slightly):
+
+    BUG: KASAN: slab-out-of-bounds in memcpy ./include/linux/string.h:341 [inline]
+    BUG: KASAN: slab-out-of-bounds in x509_fabricate_name.constprop.1+0x1a4/0x940 crypto/asymmetric_keys/x509_cert_parser.c:366
+    Read of size 128 at addr ffff880035dd9eaf by task keyctl/195
+
+    CPU: 1 PID: 195 Comm: keyctl Not tainted 4.14.0-09238-g1d3b78bbc6e9 #26
+    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-20171110_100015-anatol 04/01/2014
+    Call Trace:
+     __dump_stack lib/dump_stack.c:17 [inline]
+     dump_stack+0xd1/0x175 lib/dump_stack.c:53
+     print_address_description+0x78/0x260 mm/kasan/report.c:252
+     kasan_report_error mm/kasan/report.c:351 [inline]
+     kasan_report+0x23f/0x350 mm/kasan/report.c:409
+     memcpy+0x1f/0x50 mm/kasan/kasan.c:302
+     memcpy ./include/linux/string.h:341 [inline]
+     x509_fabricate_name.constprop.1+0x1a4/0x940 crypto/asymmetric_keys/x509_cert_parser.c:366
+     asn1_ber_decoder+0xb4a/0x1fd0 lib/asn1_decoder.c:447
+     x509_cert_parse+0x1c7/0x620 crypto/asymmetric_keys/x509_cert_parser.c:89
+     x509_key_preparse+0x61/0x750 crypto/asymmetric_keys/x509_public_key.c:174
+     asymmetric_key_preparse+0xa4/0x150 crypto/asymmetric_keys/asymmetric_type.c:388
+     key_create_or_update+0x4d4/0x10a0 security/keys/key.c:850
+     SYSC_add_key security/keys/keyctl.c:122 [inline]
+     SyS_add_key+0xe8/0x290 security/keys/keyctl.c:62
+     entry_SYSCALL_64_fastpath+0x1f/0x96
+
+    Allocated by task 195:
+     __do_kmalloc_node mm/slab.c:3675 [inline]
+     __kmalloc_node+0x47/0x60 mm/slab.c:3682
+     kvmalloc ./include/linux/mm.h:540 [inline]
+     SYSC_add_key security/keys/keyctl.c:104 [inline]
+     SyS_add_key+0x19e/0x290 security/keys/keyctl.c:62
+     entry_SYSCALL_64_fastpath+0x1f/0x96
+
+Fixes: 42d5ec27f873 ("X.509: Add an ASN.1 decoder")
+Reported-by: Alexander Potapenko <glider@google.com>
+Cc: <stable@vger.kernel.org> # v3.7+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/asn1_decoder.c |   43 ++++++++++++++++++++++++-------------------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
+
+--- a/lib/asn1_decoder.c
++++ b/lib/asn1_decoder.c
+@@ -305,38 +305,43 @@ next_op:
+       /* Decide how to handle the operation */
+       switch (op) {
+-      case ASN1_OP_MATCH_ANY_ACT:
+-      case ASN1_OP_COND_MATCH_ANY_ACT:
+-              ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
+-              if (ret < 0)
+-                      return ret;
+-              goto skip_data;
+-
+-      case ASN1_OP_MATCH_ACT:
+-      case ASN1_OP_MATCH_ACT_OR_SKIP:
+-      case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
+-              ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len);
+-              if (ret < 0)
+-                      return ret;
+-              goto skip_data;
+-
+       case ASN1_OP_MATCH:
+       case ASN1_OP_MATCH_OR_SKIP:
++      case ASN1_OP_MATCH_ACT:
++      case ASN1_OP_MATCH_ACT_OR_SKIP:
+       case ASN1_OP_MATCH_ANY:
++      case ASN1_OP_MATCH_ANY_ACT:
+       case ASN1_OP_COND_MATCH_OR_SKIP:
++      case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
+       case ASN1_OP_COND_MATCH_ANY:
+-      skip_data:
++      case ASN1_OP_COND_MATCH_ANY_ACT:
++
+               if (!(flags & FLAG_CONS)) {
+                       if (flags & FLAG_INDEFINITE_LENGTH) {
++                              size_t tmp = dp;
++
+                               ret = asn1_find_indefinite_length(
+-                                      data, datalen, &dp, &len, &errmsg);
++                                      data, datalen, &tmp, &len, &errmsg);
+                               if (ret < 0)
+                                       goto error;
+-                      } else {
+-                              dp += len;
+                       }
+                       pr_debug("- LEAF: %zu\n", len);
+               }
++
++              if (op & ASN1_OP_MATCH__ACT) {
++                      unsigned char act;
++
++                      if (op & ASN1_OP_MATCH__ANY)
++                              act = machine[pc + 1];
++                      else
++                              act = machine[pc + 2];
++                      ret = actions[act](context, hdr, tag, data + dp, len);
++                      if (ret < 0)
++                              return ret;
++              }
++
++              if (!(flags & FLAG_CONS))
++                      dp += len;
+               pc += asn1_op_lengths[op];
+               goto next_op;
index 6c3686e767166b5667d2b0f0891c130a1459309c..c549b40e573659d4c540747579fd8fcd6face4de 100644 (file)
@@ -42,6 +42,7 @@ Reported-by: syzbot+ddde1c7b7ff7442d7f2d@syzkaller.appspotmail.com
 Suggested-by: Florian Westphal <fw@strlen.de>
 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Tested-by: Krzysztof Piotr Oledzki <ole@ans.pl>
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 ---
index a0e56b4927f955b26dc9e27b1f103fd5cc47809c..b91d2d218c43faa0b16900d8d92154dce482f671 100644 (file)
@@ -10,3 +10,4 @@ irqchip-gic-v3-use-wmb-instead-of-smb_wmb-in-gic_raise_softirq.patch
 arm64-disable-unhandled-signal-log-messages-by-default.patch
 usb-dwc3-gadget-set-maxpacket-size-for-ep0-in.patch
 usb-gadget-f_fs-process-all-descriptors-during-bind.patch
+asn.1-fix-out-of-bounds-read-when-parsing-indefinite-length-item.patch