CVE-2017-13047: Out-of-bounds Read (CWE-125)
value: The ISO ES-IS parser in tcpdump before 4.9.2 has a buffer over-read in print-isoclns.c:esis_print().
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/esis_opt_prot-oobr.out, tests/esis_snpa_asan-3.out, tests/esis_snpa_asan-4.out, tests/esis_snpa_asan-5.out
Commit date: 2017-09-13 12:25:44 +0100
Commit message: CVE-2017-13047/ES-IS: put an existing bounds check right

The bounds check in esis_print() tested one pointer at the beginning of
a loop that incremented another, make the trivial fix. While at it, make
the function print a standard marker when it detects truncated data and
update some existing ES-IS tests respectively.

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).

Diff: diff --git a/print-isoclns.c b/print-isoclns.c
index 6285502845..06ad906415 100644
--- a/print-isoclns.c
+++ b/print-isoclns.c
@@ -1332,11 +1332,11 @@ esis_print(netdissect_options *ndo,
                     ND_PRINT((ndo, "(bad length)"));
                 break;
 
             case ESIS_OPTION_PROTOCOLS:
                 while (opli>0) {
-                    ND_TCHECK(*pptr);
+                    ND_TCHECK(*tptr);
                     ND_PRINT((ndo, "%s (0x%02x)",
                            tok2str(nlpid_values,
                                    "unknown",
                                    *tptr),
                            *tptr));
@@ -1365,11 +1365,11 @@ esis_print(netdissect_options *ndo,
             if (ndo->ndo_vflag > 1)
                 print_unknown_data(ndo, pptr, "\n\t  ", opli);
             pptr += opli;
         }
 trunc:
-	return;
+        ND_PRINT((ndo, "[|esis]"));
 }
 
 static void
 isis_print_mcid(netdissect_options *ndo,
                 const struct isis_spb_mcid *mcid)
diff --git a/tests/TESTLIST b/tests/TESTLIST
index d803951774..62e705bf38 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -564,10 +564,11 @@ hncp_dhcpv6data-oobr	hncp_dhcpv6data-oobr.pcap	hncp_dhcpv6data-oobr.out -v -c1
 hncp_dhcpv4data-oobr	hncp_dhcpv4data-oobr.pcap	hncp_dhcpv4data-oobr.out -v -c1
 vqp-oobr		vqp-oobr.pcap			vqp-oobr.out		-v -c1
 bgp_pmsi_tunnel-oobr	bgp_pmsi_tunnel-oobr.pcap	bgp_pmsi_tunnel-oobr.out -v -c1
 bgp_mvpn_6_and_7	bgp_mvpn_6_and_7.pcap		bgp_mvpn_6_and_7.out	-v -c1
 rsvp_fast_reroute-oobr	rsvp_fast_reroute-oobr.pcap	rsvp_fast_reroute-oobr.out -v -c1
+esis_opt_prot-oobr	esis_opt_prot-oobr.pcap		esis_opt_prot-oobr.out	-v -c1
 
 # bad packets from Katie Holly
 mlppp-oobr		mlppp-oobr.pcap			mlppp-oobr.out
 
 # bad packets from Kim Gwan Yeong
diff --git a/tests/esis_opt_prot-oobr.out b/tests/esis_opt_prot-oobr.out
new file mode 100644
index 0000000000..359eb0fa79
--- /dev/null
+++ b/tests/esis_opt_prot-oobr.out
@@ -0,0 +1,5 @@
+ES-IS, length 33559803
+	redirect (6), v: 1, checksum: 0x00c6 (unverified), holding time: 2303s, length indicator: 54
+	  00.8e
+	  SNPA (length: 0): <empty>
+	  Protocols supported Option #129, length 11, value: CLNP (0x81), [|esis]
diff --git a/tests/esis_opt_prot-oobr.pcap b/tests/esis_opt_prot-oobr.pcap
new file mode 100644
index 0000000000..c50cb67eca
Binary files /dev/null and b/tests/esis_opt_prot-oobr.pcap differ
diff --git a/tests/esis_snpa_asan-3.out b/tests/esis_snpa_asan-3.out
index 5e6a14d1dc..109d259193 100644
--- a/tests/esis_snpa_asan-3.out
+++ b/tests/esis_snpa_asan-3.out
@@ -2,6 +2,6 @@ UI 22! ES-IS, length 65565
 	unknown type: 0 (0), v: 1, checksum: 0x00a1 (incorrect should be 0x859d), holding time: 0s, length indicator: 17
 	  0x0000:  0200 04ec ff00 0000
 UI 22! ES-IS, length 2650865693
 	redirect (6), v: 1, checksum: 0x0300 (incorrect should be 0xbce5), holding time: 21480s, length indicator: 17
 	  ec.ff00.00
-	  SNPA (length: 0): <empty>
+	  SNPA (length: 0): <empty>[|esis]
diff --git a/tests/esis_snpa_asan-4.out b/tests/esis_snpa_asan-4.out
index 249b248bf8..10a52d46f6 100644
--- a/tests/esis_snpa_asan-4.out
+++ b/tests/esis_snpa_asan-4.out
@@ -5,17 +5,17 @@ UI 22! ES-IS, length 65565
 	  NET (length: 4): ec.ff00.00, bad opts/li
 UI 22! ES-IS, length 65565
 	redirect (6), v: 1, checksum: 0x7034 (incorrect should be 0x44ec), holding time: 21315s, length indicator: 16
 	  02.0400
 	  SNPA (length: 0): <empty>
-	  Unknown Option #0, length 0, value: 
+	  Unknown Option #0, length 0, value: [|esis]
 UI 32! ES-IS, length 65565
 	ESH (2), v: 1, checksum: 0x70a1 (incorrect should be 0xfb4e), holding time: 21315s, length indicator: 17
 	  Number of Source Addresses: 2
 	  NET (length: 0): isonsap_string: illegal length
 	  NET (length: 4): ec.ff00.00, bad opts/li
 UI 22! ES-IS, length 4244701213
 	redirect (6), v: 1, checksum: 0x7034 (incorrect should be 0x36fe), holding time: 21315s, length indicator: 17
 	  isonsap_string: illegal length
 	  SNPA (length: 0): <empty>
-	  NET (length: 4) 00.0000.00
+	  NET (length: 4) 00.0000.00[|esis]
 Q.922, invalid address
diff --git a/tests/esis_snpa_asan-5.out b/tests/esis_snpa_asan-5.out
index bd8c30dd2a..527214cb33 100644
--- a/tests/esis_snpa_asan-5.out
+++ b/tests/esis_snpa_asan-5.out
@@ -1,10 +1,10 @@
 UI 22! ES-IS, length 65565
 	ESH (2), v: 1, checksum: 0x70a1 (incorrect should be 0xfc4c), holding time: 21315s, length indicator: 17
 	  Number of Source Addresses: 3
 	  NET (length: 0): isonsap_string: illegal length
 	  NET (length: 4): ec.ff00.00
-	  NET (length: 0): isonsap_string: illegal length
+	  NET (length: 0): isonsap_string: illegal length[|esis]
 UI 22! ES-IS, length 65565
 	redirect (6), v: 1, checksum: 0x7034 (incorrect should be 0x3ff0), holding time: 21315s, length indicator: 17
 	  04
 	  SNPA (length: 4): 00:00:00:00, bad opts/li

Vulnerable code:                     ND_TCHECK(*pptr);
	return;
	  SNPA (length: 0): <empty>
	  Unknown Option #0, length 0, value: 
	  NET (length: 4) 00.0000.00
	  NET (length: 0): isonsap_string: illegal length
Fixed code:                     ND_TCHECK(*tptr);
        ND_PRINT((ndo, "[|esis]"));
esis_opt_prot-oobr	esis_opt_prot-oobr.pcap		esis_opt_prot-oobr.out	-v -c1
ES-IS, length 33559803
	redirect (6), v: 1, checksum: 0x00c6 (unverified), holding time: 2303s, length indicator: 54
	  00.8e
	  SNPA (length: 0): <empty>
	  Protocols supported Option #129, length 11, value: CLNP (0x81), [|esis]
	  SNPA (length: 0): <empty>[|esis]
	  Unknown Option #0, length 0, value: [|esis]
	  NET (length: 4) 00.0000.00[|esis]
	  NET (length: 0): isonsap_string: illegal length[|esis]