Code: ikev2_auth_print(netdissect_options *ndo, u_char tpay,
		const struct isakmp_gen *ext,
		u_int item_len _U_, const u_char *ep,
		uint32_t phase _U_, uint32_t doi _U_,
		uint32_t proto _U_, int depth _U_)
{
	struct ikev2_auth a;
	const char *v2_auth[]={ "invalid", "rsasig",
				"shared-secret", "dsssig" };
 	const u_char *authdata = (const u_char*)ext + sizeof(a);
 	unsigned int len;
 
	ND_TCHECK(*ext);
 	UNALIGNED_MEMCPY(&a, ext, sizeof(a));
 	ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
 	len = ntohs(a.h.len);

	/*
	 * Our caller has ensured that the length is >= 4.
	 */
	ND_PRINT((ndo," len=%u method=%s", len-4,
		  STR_OR_ID(a.auth_method, v2_auth)));
	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;
		}
	}

	return (const u_char *)ext + len;
trunc:
	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
	return NULL;
}

Commit Message: CVE-2017-13690/IKEv2: Fix some bounds checks.

Use a pointer of the correct type in ND_TCHECK(), or use ND_TCHECK2()
and provide the correct length.

While we're at it, remove the blank line between some checks and the
UNALIGNED_MEMCPY()s they protect.

Also, note the places where we print the entire payload.

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).
CWE ID: CWE-125
ikev2_auth_print(netdissect_options *ndo, u_char tpay,
		const struct isakmp_gen *ext,
		u_int item_len _U_, const u_char *ep,
		uint32_t phase _U_, uint32_t doi _U_,
		uint32_t proto _U_, int depth _U_)
{
	struct ikev2_auth a;
	const char *v2_auth[]={ "invalid", "rsasig",
				"shared-secret", "dsssig" };
 	const u_char *authdata = (const u_char*)ext + sizeof(a);
 	unsigned int len;
 
	ND_TCHECK2(*ext, sizeof(a));
 	UNALIGNED_MEMCPY(&a, ext, sizeof(a));
 	ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
 	len = ntohs(a.h.len);

	/*
	 * Our caller has ensured that the length is >= 4.
	 */
	ND_PRINT((ndo," len=%u method=%s", len-4,
		  STR_OR_ID(a.auth_method, v2_auth)));
	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;
		}
	}

	return (const u_char *)ext + len;
trunc:
	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
	return NULL;
}
