CVE-2017-12990 (Other, published 2017-09-14T06:29Z)
Description: value: The ISAKMP parser in tcpdump before 4.9.2 could enter an infinite loop due to bugs in print-isakmp.c, several functions.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-835 \u2014 Loop with Unreachable Exit Condition ('Infinite Loop')
The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.
Repository: https://github.com/the-tcpdump-group/tcpdump
Files changed:
print-isakmp.c
tests/TESTLIST
tests/isakmp-no-none-np.out
Commit message: CVE-2017-12990/Fix printing of ISAKMPv1 Notification payload data.

The closest thing to a specification for the contents of the payload
data is draft-ietf-ipsec-notifymsg-04, and nothing in there says that it
is ever a complete ISAKMP message, so don't dissect types we don't have
specific code for as a complete ISAKMP message.

While we're at it, fix a comment, and clean up printing of V1 Nonce,
V2 Authentication payloads, and v2 Notice payloads.

This fixes an infinite loop discovered by Forcepoint's security
researchers Otto Airamo & Antti Levomäki.

Add a test using the capture file supplied by the reporter(s).


Vulnerable code:
/* 3.8 Notification Payload */
	ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
		ND_PRINT((ndo," "));
		if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
			goto trunc;
	} else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
		ND_PRINT((ndo," "));
		if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep))
			goto trunc;
	      const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
	      uint32_t proto0 _U_, int depth)
		ND_PRINT((ndo," orig=("));
			break;
		case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
			if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
					    (const struct isakmp_gen *)cp, ep, phase, doi, proto,
					    depth) == NULL)
				return NULL;
			/* NULL is dummy */
			isakmp_print(ndo, cp,
				     item_len - sizeof(*p) - n.spi_size,
				     NULL);
		ND_PRINT((ndo,")"));
	ND_PRINT((ndo," len=%d method=%s", len-4,

	if (1 < ndo->ndo_vflag && 4 < len) {
		ND_PRINT((ndo," authdata=("));
		if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
			goto trunc;
		ND_PRINT((ndo,") "));
	} else if(ndo->ndo_vflag && 4 < len) {
		if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
	u_char showspi, showdata, showsomedata;
	showdata = 0;
		showdata= 0;
	if(3 < ndo->ndo_vflag) {
		showdata = 1;
	}

	if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
		ND_PRINT((ndo," data=("));
		if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
			goto trunc;

		ND_PRINT((ndo,")"));
	} else if(showsomedata && cp < ep) {
		if(!ike_show_somedata(ndo, cp, ep)) goto trunc;





Fixed code:
/* 3.8 Authentication Payload */
	/*
	 * Our caller has ensured that the length is >= 4.
	 */
	ND_PRINT((ndo," n len=%u", ntohs(e.len) - 4));
	if (ntohs(e.len) > 4) {
		if (ndo->ndo_vflag > 2) {
			ND_PRINT((ndo, " "));
			if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
				goto trunc;
		} else if (ndo->ndo_vflag > 1) {
			ND_PRINT((ndo, " "));
			if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep))
				goto trunc;
		}
	      const u_char *ep, uint32_t phase _U_, uint32_t doi0 _U_,
	      uint32_t proto0 _U_, int depth _U_)
			ND_PRINT((ndo," attrs=("));
			ND_PRINT((ndo,")"));
			ND_PRINT((ndo," status=("));
			ND_PRINT((ndo,")"));
			/*
			 * XXX - fill in more types here; see, for example,
			 * draft-ietf-ipsec-notifymsg-04.
			 */
			if (ndo->ndo_vflag > 3) {
				ND_PRINT((ndo," data=("));
				if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
					goto trunc;
				ND_PRINT((ndo,")"));
			} else {
				if (!ike_show_somedata(ndo, cp, ep))
					goto trunc;
			}
			break;
	/*
	 * Our caller has ensured that the length is >= 4.
	 */
	ND_PRINT((ndo," len=%u method=%s", len-4,
	if (len > 4) {
		if (ndo->ndo_vflag > 1) {
			ND_PRINT((ndo, " authdata=("));
			if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
				goto trunc;
			ND_PRINT((ndo, ") "));
		} else if (ndo->ndo_vflag) {
			if (!ike_show_somedata(ndo, authdata, ep))
				goto trunc;
		}
	u_char showspi, showsomedata;
	if (cp < ep) {
		if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) {
			ND_PRINT((ndo," data=("));
			if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
				goto trunc;
			ND_PRINT((ndo,")"));
		} else if (showsomedata) {
			if (!ike_show_somedata(ndo, cp, ep))
				goto trunc;
		}
isakmp-no-none-np	isakmp-no-none-np.pcap		isakmp-no-none-np.out	-vvv -e
00:0c:29:86:c8:36 > 00:1a:4b:6a:ce:fe, ethertype IPv4 (0x0800), length 2228: (tos 0x0, ttl 128, id 28793, offset 0, flags [none], proto UDP (17), length 2214)
    192.168.1.25.500 > 192.168.1.10.500: [udp sum ok] isakmp 1.0 msgid 5f724dc6 cookie 0000000000000000->0000000000000000: phase 2/others ? inf:
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=000000000b1005005f724dc600000054 data=(0b00001c000000010110...0100000700000000000000000000000000000000))
    (n: doi=ipsec proto=isakmp type=INVALID-MAJOR-VERSION spi=0000000000000000000000000010ba00 data=(00ff1d00020082001101...0100000700000000000000000000000000000000)) [|n] (len mismatch: isakmp 84/ip 2186)