For what it's worth, I can reproduce this in stretch by rebuilding with
ASAN (-lasan -fsanitize=address -fno-omit-frame-pointer).

I can also reproduce this in wheezy by running it in valgrind:

$ valgrind /usr/sbin/tcpdump -ntr poc
==26648== Memcheck, a memory error detector
==26648== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==26648== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==26648== Command: /usr/sbin/tcpdump -ntr poc
==26648== 
reading from file poc, link-type EN10MB (Ethernet)
IP 192.168.1.94.61358 > 239.255.255.250.1900: UDP, length 133
ARP, Reply 192.168.1.1 is-at 00:e0:20:1c:27:77, length 46
==26648== Invalid read of size 2
==26648==    at 0x1AA1F7: ??? (in /usr/sbin/tcpdump)
==26648==    by 0x17C810: ??? (in /usr/sbin/tcpdump)
==26648==    by 0x15E4F2: ??? (in /usr/sbin/tcpdump)
==26648==    by 0x13FCBD: ??? (in /usr/sbin/tcpdump)
==26648==    by 0x13C33E: ??? (in /usr/sbin/tcpdump)
==26648==    by 0x404446F: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0)
==26648==    by 0x4035ECE: pcap_loop (in 
/usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0)
==26648==    by 0x13AE68: main (in /usr/sbin/tcpdump)
==26648==  Address 0x59d168f is 3 bytes after a block of size 60 alloc'd
==26648==    at 0x4C28BED: malloc (vg_replace_malloc.c:263)
==26648==    by 0x4044F1B: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0)
==26648==    by 0x4044722: pcap_fopen_offline (in 
/usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0)
==26648==    by 0x40448EF: pcap_open_offline (in 
/usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0)
==26648==    by 0x13AB4B: main (in /usr/sbin/tcpdump)
==26648== 
STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 175[|stp 
175]
IP 192.168.1.131.5353 > 224.0.0.251.5353: 0 [2q] [2n][|domain]
IP 192.168.1.209.5353 > 224.0.0.251.5353: 0*- [0q] 2/0/0[|domain]

Also: there's something fishy with that POC file. I can extract the rar
file in a stretch virtualbox instance, but not out of the box, nor under
wheezy. Something odd there.

I'm trying to figure out exactly how to fix this, at this stage. It
doesn't look like upstream responded just yet, but I can already say the
following.

 1. tcpdump does try to derefence a pointer with an address value that
    is user-controlled (mstp_len) in print-stp.c:478

 2. even when tcpdump doesn't crash, it fails to render the packet
    properly. with -vvv, i get this:

    STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward, Agreement], length 175
            port-role Designated, CIST root-id 8000.20:bb:c0:7b:d1:2e, CIST 
ext-pathcost 0
            CIST regional-root-id 8000.20:bb:c0:7b:d1:2e, CIST port-id 8002,
            message-age 0.00s, max-age 20.00s, hello-time 2.00s, 
forwarding-delay 15.00s
            v3len 8, [|stp 175]

    notice the trailing comma there: after the `v3len` field, there
    would normally be other things there, but some overflow detection
    kicks in stp_print_mstp_bpdu(), which, in turns, calls the magic
    ND_TCHECK macro which detects the overflow and bails out properly

 3. therefore, -vvv doesn't trigger the bug

 4. conclusion: it may be simply a matter of calling the proper
    ND_TCHECK macro before dereferencing the pointer.

Therefore, the following debdiff should fix this.

A.
diff -Nru tcpdump-4.9.0/debian/changelog tcpdump-4.9.0/debian/changelog
--- tcpdump-4.9.0/debian/changelog      2017-01-29 16:17:21.000000000 -0500
+++ tcpdump-4.9.0/debian/changelog      2017-07-19 18:18:26.000000000 -0400
@@ -1,3 +1,14 @@
+tcpdump (4.9.0-1~deb7u2) UNRELEASED; urgency=high
+
+  * Non-maintainer upload by the Security Team.
+  * CVE-2017-11108: tcpdump 4.9.0 allows remote attackers to cause a
+    denial of service (heap-based buffer over-read and application crash)
+    via crafted packet data. The crash occurs in the EXTRACT_16BITS
+    function, called from the stp_print function for the Spanning Tree
+    Protocol. (Closes: #867718)
+
+ -- Antoine Beaupré <anar...@debian.org>  Wed, 19 Jul 2017 18:18:26 -0400
+
 tcpdump (4.9.0-1~deb7u1) wheezy-security; urgency=high
 
   * Backport to wheezy.
diff -Nru tcpdump-4.9.0/debian/patches/CVE-2017-11108.patch 
tcpdump-4.9.0/debian/patches/CVE-2017-11108.patch
--- tcpdump-4.9.0/debian/patches/CVE-2017-11108.patch   1969-12-31 
19:00:00.000000000 -0500
+++ tcpdump-4.9.0/debian/patches/CVE-2017-11108.patch   2017-07-19 
18:16:26.000000000 -0400
@@ -0,0 +1,10 @@
+--- ./print-stp.c.orig 2017-07-19 18:13:41.163742974 -0400
++++ ./print-stp.c      2017-07-19 18:13:52.043952596 -0400
+@@ -475,6 +475,7 @@
+             if (stp_bpdu->protocol_version == STP_PROTO_SPB)
+             {
+               /* Validate v4 length */
++              ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
+               spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + 
mstp_len);
+               spb_len += 2;
+               if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) ||
diff -Nru tcpdump-4.9.0/debian/patches/series 
tcpdump-4.9.0/debian/patches/series
--- tcpdump-4.9.0/debian/patches/series 2017-01-28 06:00:46.000000000 -0500
+++ tcpdump-4.9.0/debian/patches/series 2017-07-19 18:16:26.000000000 -0400
@@ -2,3 +2,4 @@
 man-section.diff
 platform-quirks.diff
 disable-tests.diff
+CVE-2017-11108.patch

Attachment: signature.asc
Description: PGP signature

Reply via email to