Code: l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat)
 {
 	const uint16_t *ptr = (const uint16_t *)dat;
 	uint16_t val_h, val_l;
 
 	ptr++;		/* skip "Reserved" */
 
	val_h = EXTRACT_16BITS(ptr); ptr++;
	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
 
	val_h = EXTRACT_16BITS(ptr); ptr++;
	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
 
	val_h = EXTRACT_16BITS(ptr); ptr++;
	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
 
	val_h = EXTRACT_16BITS(ptr); ptr++;
	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
 
	val_h = EXTRACT_16BITS(ptr); ptr++;
	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
 
 	val_h = EXTRACT_16BITS(ptr); ptr++;
 	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
 }

Commit Message: CVE-2017-13006/L2TP: Check whether an AVP's content exceeds the AVP length.

It's not good enough to check whether all the data specified by the AVP
length was captured - you also have to check whether that length is
large enough for all the required data in the AVP.

This fixes a buffer over-read discovered by Yannick Formaggio.

Add a test using the capture file supplied by the reporter(s).
CWE ID: CWE-125
l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat)
l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
 {
 	const uint16_t *ptr = (const uint16_t *)dat;
 	uint16_t val_h, val_l;
 
	if (length < 2) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
 	ptr++;		/* skip "Reserved" */
	length -= 2;
 
	if (length < 4) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
	val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
	val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
 	ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
 
	if (length < 4) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
	val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
	val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
 	ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
 
	if (length < 4) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
	val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
	val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
 	ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
 
	if (length < 4) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
	val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
	val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
 	ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
 
	if (length < 4) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
	val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
	val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
 	ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
 
	if (length < 4) {
		ND_PRINT((ndo, "AVP too short"));
		return;
	}
 	val_h = EXTRACT_16BITS(ptr); ptr++;
 	val_l = EXTRACT_16BITS(ptr); ptr++;
 	ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
 }
