CVE-2017-13018: Out-of-bounds Read (CWE-125)
value: The PGM parser in tcpdump before 4.9.2 has a buffer over-read in print-pgm.c:pgm_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-pgm.c, tests/TESTLIST, tests/pgm_opts_asan.out
Commit date: 2017-09-13 12:25:44 +0100
Commit message: CVE-2017-13018/PGM: Add a missing bounds check.

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-pgm.c b/print-pgm.c
index 6d5c01ce11..9bd6eac535 100644
--- a/print-pgm.c
+++ b/print-pgm.c
@@ -455,10 +455,14 @@ pgm_print(netdissect_options *ndo,
 	    while (opts_len) {
 		if (opts_len < PGM_MIN_OPT_LEN) {
 		    ND_PRINT((ndo, "[Total option length leaves no room for final option]"));
 		    return;
 		}
+		if (!ND_TTEST2(*bp, 2)) {
+		    ND_PRINT((ndo, " [|OPT]"));
+		    return;
+		}
 		opt_type = *bp++;
 		opt_len = *bp++;
 		if (opt_len < PGM_MIN_OPT_LEN) {
 		    ND_PRINT((ndo, "[Bad option, length %u < %u]", opt_len,
 		        PGM_MIN_OPT_LEN));
diff --git a/tests/TESTLIST b/tests/TESTLIST
index 3f5726601b..68617bf44a 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -517,10 +517,11 @@ esis_snpa_asan		esis_snpa_asan.pcap		esis_snpa_asan.out	-v
 esis_snpa_asan-2	esis_snpa_asan-2.pcap		esis_snpa_asan-2.out	-v
 esis_snpa_asan-3	esis_snpa_asan-3.pcap		esis_snpa_asan-3.out	-v
 esis_snpa_asan-4	esis_snpa_asan-4.pcap		esis_snpa_asan-4.out	-v
 esis_snpa_asan-5	esis_snpa_asan-5.pcap		esis_snpa_asan-5.out	-v
 dhcp6_reconf_asan	dhcp6_reconf_asan.pcap		dhcp6_reconf_asan.out	-v
+pgm_opts_asan		pgm_opts_asan.pcap		pgm_opts_asan.out	-v
 
 # RTP tests
 # fuzzed pcap
 rtp-seg-fault-1  rtp-seg-fault-1.pcap  rtp-seg-fault-1.out  -v -T rtp
 rtp-seg-fault-2  rtp-seg-fault-2.pcap  rtp-seg-fault-2.out  -v -T rtp
diff --git a/tests/pgm_opts_asan.out b/tests/pgm_opts_asan.out
new file mode 100644
index 0000000000..cc0607a457
--- /dev/null
+++ b/tests/pgm_opts_asan.out
@@ -0,0 +1,2 @@
+IP (tos 0x41,ECT(1), id 0, offset 0, flags [none], proto PGM (113), length 32639, options (unknown 89 [bad length 232]), bad cksum 5959 (->9eb9)!)
+    128.121.89.107 > 89.89.16.63: 128.121.89.107.4 > 89.89.16.63.225: PGM, length 0 0x3414eb1f0022 UNKNOWN type 0x1f OPTS LEN 225 OPT_1F [13]  OPT_06 [26]  PATH_NLA [4] [|OPT]
diff --git a/tests/pgm_opts_asan.pcap b/tests/pgm_opts_asan.pcap
new file mode 100644
index 0000000000..f65d06a0d1
Binary files /dev/null and b/tests/pgm_opts_asan.pcap differ

Fixed code: 		if (!ND_TTEST2(*bp, 2)) {
		    ND_PRINT((ndo, " [|OPT]"));
		    return;
		}
pgm_opts_asan		pgm_opts_asan.pcap		pgm_opts_asan.out	-v
IP (tos 0x41,ECT(1), id 0, offset 0, flags [none], proto PGM (113), length 32639, options (unknown 89 [bad length 232]), bad cksum 5959 (->9eb9)!)
    128.121.89.107 > 89.89.16.63: 128.121.89.107.4 > 89.89.16.63.225: PGM, length 0 0x3414eb1f0022 UNKNOWN type 0x1f OPTS LEN 225 OPT_1F [13]  OPT_06 [26]  PATH_NLA [4] [|OPT]