CVE-2017-13048: Out-of-bounds Read (CWE-125)
value: The RSVP parser in tcpdump before 4.9.2 has a buffer over-read in print-rsvp.c:rsvp_obj_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-rsvp.c, tests/TESTLIST, tests/rsvp_fast_reroute-oobr.out
Commit date: 2017-09-13 12:25:44 +0100
Commit message: CVE-2017-13048/RSVP: fix decoding of Fast Reroute objects

In rsvp_obj_print() the case block for Class-Num 205 (FAST_REROUTE) from
RFC 4090 Section 4.1 could over-read accessing the buffer contents before
making the bounds check. Rearrange those steps the correct way around.

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-rsvp.c b/print-rsvp.c
index 1eccb4875f..bc599796a8 100644
--- a/print-rsvp.c
+++ b/print-rsvp.c
@@ -1470,16 +1470,16 @@ rsvp_obj_print(netdissect_options *ndo,
             break;
 
         case RSVP_OBJ_FASTREROUTE:
             /* the differences between c-type 1 and 7 are minor */
             obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
-            bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
 
             switch(rsvp_obj_ctype) {
             case RSVP_CTYPE_1: /* new style */
                 if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
                     return-1;
+                bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
                 ND_PRINT((ndo, "%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
                        ident,
                        (int)obj_ptr.rsvp_obj_frr->setup_prio,
                        (int)obj_ptr.rsvp_obj_frr->hold_prio,
                        (int)obj_ptr.rsvp_obj_frr->hop_limit,
@@ -1494,10 +1494,11 @@ rsvp_obj_print(netdissect_options *ndo,
                 break;
 
             case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
                 if (obj_tlen < 16)
                     return-1;
+                bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
                 ND_PRINT((ndo, "%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
                        ident,
                        (int)obj_ptr.rsvp_obj_frr->setup_prio,
                        (int)obj_ptr.rsvp_obj_frr->hold_prio,
                        (int)obj_ptr.rsvp_obj_frr->hop_limit,
diff --git a/tests/TESTLIST b/tests/TESTLIST
index 08cb0d9ac0..d803951774 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -563,10 +563,11 @@ hncp_dhcpv6data-oobr	hncp_dhcpv6data-oobr.pcap	hncp_dhcpv6data-oobr.out -v -c1
 # Same comments apply to the case below.
 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
 
 # bad packets from Katie Holly
 mlppp-oobr		mlppp-oobr.pcap			mlppp-oobr.out
 
 # bad packets from Kim Gwan Yeong
diff --git a/tests/rsvp_fast_reroute-oobr.out b/tests/rsvp_fast_reroute-oobr.out
new file mode 100644
index 0000000000..0ca2a684b4
--- /dev/null
+++ b/tests/rsvp_fast_reroute-oobr.out
@@ -0,0 +1,6 @@
+IP (tos 0x0, ttl 224, id 17920, offset 0, flags [none], proto RSVP (46), length 42024, bad cksum 3700 (->fc41)!)
+    0.203.243.128 > 0.26.0.0: 
+	RSVPv1 Path Message (1), Flags: [Refresh reduction capable], length: 41218, ttl: 227, checksum: 0x00f4
+	  Fast Re-Route Object (205) Flags: [ignore and forward if unknown], Class-Type: Unknown (0), length: 4
+	  Fast Re-Route Object (205) Flags: [ignore and forward if unknown], Class-Type: Unknown (0), length: 4
+		 [|rsvp]
diff --git a/tests/rsvp_fast_reroute-oobr.pcap b/tests/rsvp_fast_reroute-oobr.pcap
new file mode 100644
index 0000000000..cc1d72e252
Binary files /dev/null and b/tests/rsvp_fast_reroute-oobr.pcap differ

Vulnerable code:             bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
Fixed code:                 bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
                bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
rsvp_fast_reroute-oobr	rsvp_fast_reroute-oobr.pcap	rsvp_fast_reroute-oobr.out -v -c1
IP (tos 0x0, ttl 224, id 17920, offset 0, flags [none], proto RSVP (46), length 42024, bad cksum 3700 (->fc41)!)
    0.203.243.128 > 0.26.0.0: 
	RSVPv1 Path Message (1), Flags: [Refresh reduction capable], length: 41218, ttl: 227, checksum: 0x00f4
	  Fast Re-Route Object (205) Flags: [ignore and forward if unknown], Class-Type: Unknown (0), length: 4
	  Fast Re-Route Object (205) Flags: [ignore and forward if unknown], Class-Type: Unknown (0), length: 4
		 [|rsvp]