CVE-2017-13035: Out-of-bounds Read (CWE-125)
value: The ISO IS-IS parser in tcpdump before 4.9.2 has a buffer over-read in print-isoclns.c:isis_print_id().
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 9.8
Published: 2017-09-14T06:29Z
Repository: https://github.com/the-tcpdump-group/tcpdump
Language: Other
Files changed: print-isoclns.c, tests/TESTLIST, tests/isis_sysid_asan.out
Commit date: 2017-09-13 12:25:44 +0100
Commit message: CVE-2017-13035/Properly handle IS-IS IDs shorter than a system ID (MAC address).

Some of them are variable-length, with a field giving the total length,
and therefore they can be shorter than 6 octets.  If one is, don't run
past the end.

This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add a test using the capture file supplied by the reporter(s), modified
so the capture file won't be rejected as an invalid capture.

Diff: diff --git a/print-isoclns.c b/print-isoclns.c
index eb22759be2..6285502845 100644
--- a/print-isoclns.c
+++ b/print-isoclns.c
@@ -1644,12 +1644,16 @@ static char *
 isis_print_id(const uint8_t *cp, int id_len)
 {
     int i;
     static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
     char *pos = id;
+    int sysid_len;
 
-    for (i = 1; i <= SYSTEM_ID_LEN; i++) {
+    sysid_len = SYSTEM_ID_LEN;
+    if (sysid_len > id_len)
+        sysid_len = id_len;
+    for (i = 1; i <= sysid_len; i++) {
         snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
 	pos += strlen(pos);
 	if (i == 2 || i == 4)
 	    *pos++ = '.';
 	}
diff --git a/tests/TESTLIST b/tests/TESTLIST
index 1c94dcca16..3adc5c7f37 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -537,10 +537,11 @@ mobility_opt_asan_6	mobility_opt_asan_6.pcap	mobility_opt_asan_6.out	-v
 mobility_opt_asan_7	mobility_opt_asan_7.pcap	mobility_opt_asan_7.out	-v
 isis_stlv_asan		isis_stlv_asan.pcap		isis_stlv_asan.out	-v
 isis_stlv_asan-2	isis_stlv_asan-2.pcap		isis_stlv_asan-2.out	-v
 isis_stlv_asan-3	isis_stlv_asan-3.pcap		isis_stlv_asan-3.out	-v
 isis_stlv_asan-4	isis_stlv_asan-4.pcap		isis_stlv_asan-4.out	-v
+isis_sysid_asan		isis_sysid_asan.pcap		isis_sysid_asan.out	-v
 lldp_mgmt_addr_tlv_asan	lldp_mgmt_addr_tlv_asan.pcap	lldp_mgmt_addr_tlv_asan.out	-v
 bootp_asan		bootp_asan.pcap			bootp_asan.out		-v
 bootp_asan-2		bootp_asan-2.pcap		bootp_asan-2.out	-v
 ppp_ccp_config_deflate_option_asan	ppp_ccp_config_deflate_option_asan.pcap	ppp_ccp_config_deflate_option_asan.out	-v
 pim_header_asan		pim_header_asan.pcap		pim_header_asan.out	-v
diff --git a/tests/isis_sysid_asan.out b/tests/isis_sysid_asan.out
new file mode 100644
index 0000000000..0e5a703334
--- /dev/null
+++ b/tests/isis_sysid_asan.out
@@ -0,0 +1,71 @@
+UI 22! IS-IS, length 469869187
+	L2 Lan IIH, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 224 (224)
+	  source-id: fed0.f90f.58af,  holding time: 34047s, Flags: [unknown circuit type 0x00]
+	  lan-id:    0105.0088.a204.00, Priority: 65, PDU length: 4096
+	    unknown TLV #64, length: 128
+		0x0000:  ff10 8e12 0001 1b01 0000 6b00 fbcf f90f
+		0x0010:  58af 84ff 1000 4901 0000 88a2 011c 000c
+		0x0020:  0281 0083 1b01 0010 019d e000 fed0 f90f
+		0x0030:  58af 84ff 1000 4101 0500 88a2 011c 0272
+		0x0040:  0c2a 2205 831b 011c 0010 0000 0583 1b01
+		0x0050:  0010 01ab e000 fe08 0808 0808 08cb 0808
+		0x0060:  0808 0808 0808 0880 0008 7f08 0808 0808
+		0x0070:  08fd 0808 080c 0608 0807 0808 0808 0408
+	    Padding TLV #8, length: 8
+	    Padding TLV #8, length: 8
+	    Padding TLV #8, length: 7
+	    Padding TLV #8, length: 8
+	    Padding TLV #8, length: 0
+	    Padding TLV #8, length: 8
+	    unknown TLV #100, length: 0
+	    unknown TLV #32, length: 16
+		0x0000:  2020 2020 3c20 2020 2020 2020 205a 1a31
+	    IS Neighbor(s) (variable length) TLV #7, length: 238
+	      LAN address length 1 bytes 
+		IS Neighbor: 5a
+		IS Neighbor: 45
+		IS Neighbor: 50
+		IS Neighbor: 48
+		IS Neighbor: 59
+		IS Neighbor: 52
+		IS Neighbor: 5f
+		IS Neighbor: 43
+		IS Neighbor: 54
+		IS Neighbor: 4c
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 08
+		IS Neighbor: 00
+		IS Neighbor: 00
+		IS Neighbor: 08
+		IS Neighbor: 00
+		IS Neighbor: 20
+		IS Neighbor: 64
+		IS Neighbor: 00
+		IS Neighbor: 20
+		IS Neighbor: 10
+		IS Neighbor: 20
+		IS Neighbor: 20
+		IS Neighbor: 20
+		IS Neighbor: 20
+		IS Neighbor: 20
+		IS Neighbor: 20
+		IS Neighbor: 20
+		IS Neighbor: 20 [|isis]
diff --git a/tests/isis_sysid_asan.pcap b/tests/isis_sysid_asan.pcap
new file mode 100644
index 0000000000..8190b4e655
Binary files /dev/null and b/tests/isis_sysid_asan.pcap differ

Vulnerable code:     for (i = 1; i <= SYSTEM_ID_LEN; i++) {
Fixed code:     int sysid_len;
    sysid_len = SYSTEM_ID_LEN;
    if (sysid_len > id_len)
        sysid_len = id_len;
    for (i = 1; i <= sysid_len; i++) {
isis_sysid_asan		isis_sysid_asan.pcap		isis_sysid_asan.out	-v
UI 22! IS-IS, length 469869187
	L2 Lan IIH, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 224 (224)
	  source-id: fed0.f90f.58af,  holding time: 34047s, Flags: [unknown circuit type 0x00]
	  lan-id:    0105.0088.a204.00, Priority: 65, PDU length: 4096
	    unknown TLV #64, length: 128
		0x0000:  ff10 8e12 0001 1b01 0000 6b00 fbcf f90f
		0x0010:  58af 84ff 1000 4901 0000 88a2 011c 000c
		0x0020:  0281 0083 1b01 0010 019d e000 fed0 f90f
		0x0030:  58af 84ff 1000 4101 0500 88a2 011c 0272
		0x0040:  0c2a 2205 831b 011c 0010 0000 0583 1b01
		0x0050:  0010 01ab e000 fe08 0808 0808 08cb 0808
		0x0060:  0808 0808 0808 0880 0008 7f08 0808 0808
		0x0070:  08fd 0808 080c 0608 0807 0808 0808 0408
	    Padding TLV #8, length: 8
	    Padding TLV #8, length: 8
	    Padding TLV #8, length: 7
	    Padding TLV #8, length: 8
	    Padding TLV #8, length: 0
	    Padding TLV #8, length: 8
	    unknown TLV #100, length: 0
	    unknown TLV #32, length: 16
		0x0000:  2020 2020 3c20 2020 2020 2020 205a 1a31
	    IS Neighbor(s) (variable length) TLV #7, length: 238
	      LAN address length 1 bytes 
		IS Neighbor: 5a
		IS Neighbor: 45
		IS Neighbor: 50
		IS Neighbor: 48
		IS Neighbor: 59
		IS Neighbor: 52
		IS Neighbor: 5f
		IS Neighbor: 43
		IS Neighbor: 54
		IS Neighbor: 4c
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 08
		IS Neighbor: 00
		IS Neighbor: 00
		IS Neighbor: 08
		IS Neighbor: 00
		IS Neighbor: 20
		IS Neighbor: 64
		IS Neighbor: 00
		IS Neighbor: 20
		IS Neighbor: 10
		IS Neighbor: 20
		IS Neighbor: 20
		IS Neighbor: 20
		IS Neighbor: 20
		IS Neighbor: 20
		IS Neighbor: 20
		IS Neighbor: 20
		IS Neighbor: 20 [|isis]