CVE-2017-13051 (Other, published 2017-09-14T06:29Z)
Description: value: The RSVP parser in tcpdump before 4.9.2 has a buffer over-read in print-rsvp.c:rsvp_obj_print().
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/the-tcpdump-group/tcpdump
Files changed:
print-rsvp.c
tests/TESTLIST
tests/rsvp_uni-oobr-1.out
tests/rsvp_uni-oobr-2.out
tests/rsvp_uni-oobr-3.out
Commit message: CVE-2017-13051/RSVP: fix bounds checks for UNI

Fixup the part of rsvp_obj_print() that decodes the GENERALIZED_UNI
object from RFC 3476 Section 3.1 to check the sub-objects inside that
object more thoroughly.

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


Vulnerable code:
                    if(subobj_len == 0)

Fixed code:
                    /* If RFC 3476 Section 3.1 defined that a sub-object of the
                     * GENERALIZED_UNI RSVP object must have the Length field as
                     * a multiple of 4, instead of the check below it would be
                     * better to test total_subobj_len only once before the loop.
                     * So long as it does not define it and this while loop does
                     * not implement such a requirement, let's accept that within
                     * each iteration subobj_len may happen to be a multiple of 1
                     * and test it and total_subobj_len respectively.
                     */
                    if (total_subobj_len < 4)
                        goto invalid;
                    /* In addition to what is explained above, the same spec does not
                     * explicitly say that the same Length field includes the 4-octet
                     * sub-object header, but as long as this while loop implements it
                     * as it does include, let's keep the check below consistent with
                     * the rest of the code.
                     */
                    if(subobj_len < 4 || subobj_len > total_subobj_len)
rsvp_uni-oobr-1	rsvp_uni-oobr-1.pcap	rsvp_uni-oobr-1.out	-v -c1
rsvp_uni-oobr-2	rsvp_uni-oobr-2.pcap	rsvp_uni-oobr-2.out	-v -c1
rsvp_uni-oobr-3	rsvp_uni-oobr-3.pcap	rsvp_uni-oobr-3.out	-v -c3
IP (tos 0x2,ECT(0), ttl 248, id 0, offset 0, flags [none], proto RSVP (46), length 54312, bad cksum 3743 (->7e72)!)
    54.35.0.0 > 58.16.0.0: 
	RSVPv1 Hello Message (20), Flags: [Refresh reduction capable], length: 65527, ttl: 15, checksum: 0x0902
	  Generalized UNI Object (229) Flags: [ignore and forward if unknown], Class-Type: 1 (1), length: 12
	    Subobject Type: Unknown (127), AF: HDLC (4), length: 2 (invalid)
IP (tos 0x2,ECT(0), ttl 248, id 0, offset 0, flags [none], proto RSVP (46), length 54312, bad cksum 3743 (->3051)!)
    54.35.78.33 > 58.16.0.0: 
	RSVPv1 Hello Message (20), Flags: [Refresh reduction capable], length: 65527, ttl: 15, checksum: 0x0902
	  Generalized UNI Object (229) Flags: [ignore and forward if unknown], Class-Type: 1 (1), length: 12
	    Subobject Type: Unknown (0), AF: HDLC (4), length: 2 (invalid)
IP (tos 0x0, ttl 48, id 25615, offset 0, flags [+, DF, rsvd], proto UDP (17), length 61735, bad cksum 8ef1 (->10e1)!)
    1.2.3.3.1812 > 64.112.0.96.4567:  wb-29!
IP (tos 0x2,ECT(0), ttl 248, id 0, offset 0, flags [none], proto RSVP (46), length 54312, bad cksum 3701 (->8972)!)
    54.35.0.0 > 47.16.0.0: 
	RSVPv1 Hello Message (20), Flags: [Refresh reduction capable], length: 65527, ttl: 15, checksum: 0x0902
	  Generalized UNI Object (229) Flags: [ignore and forward if unknown], Class-Type: 1 (1), length: 12
	    Subobject Type: Unknown (0), AF: HDLC (4), length: 1 (invalid)
IP (tos 0x2,ECT(0), ttl 248, id 0, offset 0, flags [none], proto RSVP (46), length 54312, bad cksum 3701 (->7e72)!)
    54.35.0.0 > 58.16.0.0: 
	RSVPv1 Hello Message (20), Flags: [Refresh reduction capable], length: 65527, ttl: 15, checksum: 0x0902
	  Generalized UNI Object (229) Flags: [ignore and forward if unknown], Class-Type: 1 (1), length: 12
	    Subobject Type: Unknown (225), AF: HDLC (4), length: 1 (invalid)