From: Guy Harris Date: Sun, 14 Nov 2021 02:50:02 +0000 (-0800) Subject: EAP: add some more length checks. X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/50dfa7ecebfef0f954f3ac2e6bbbf84ab468f848 EAP: add some more length checks. Check to make sure we don't go past the length value in the header. Note that the string in an Identity message is optional (so we just don't bother printing it if it's zero-length), but the string in a notification message isn't (so report an error if it's zero-length). --- diff --git a/print-eap.c b/print-eap.c index 42b22f62..04acccb2 100644 --- a/print-eap.c +++ b/print-eap.c @@ -171,11 +171,19 @@ eap_print(netdissect_options *ndo, type, GET_U_1((cp + 1)), len); + if (len < 4) { + ND_PRINT(" (too short for EAP header)"); + return; + } ND_TCHECK_LEN(cp, len); if (type == EAP_REQUEST || type == EAP_RESPONSE) { /* RFC 3748 Section 4.1 */ + if (len < 5) { + ND_PRINT(" (too short for EAP request/response)"); + return; + } subtype = GET_U_1(cp + 4); ND_PRINT("\n\t\t Type %s (%u)", tok2str(eap_type_values, "unknown", subtype), @@ -183,6 +191,7 @@ eap_print(netdissect_options *ndo, switch (subtype) { case EAP_TYPE_IDENTITY: + /* According to RFC 3748, the message is optional */ if (len > 5 ) { ND_PRINT(", Identity: "); nd_printjnp(ndo, cp + 5, len - 5); @@ -190,10 +199,13 @@ eap_print(netdissect_options *ndo, break; case EAP_TYPE_NOTIFICATION: - if (len > 5) { - ND_PRINT(", Notification: "); - nd_printjnp(ndo, cp + 5, len - 5); + /* According to RFC 3748, there must be at least one octet of message */ + if (len < 6) { + ND_PRINT(" (too short for EAP Notification request/response)"); + return; } + ND_PRINT(", Notification: "); + nd_printjnp(ndo, cp + 5, len - 5); break; case EAP_TYPE_NAK: @@ -202,6 +214,10 @@ eap_print(netdissect_options *ndo, * the desired authentication * type one octet per type */ + if (len < 6) { + ND_PRINT(" (too short for EAP Legacy NAK request/response)"); + return; + } for (count = 5; count < len; count++) { ND_PRINT(" %s (%u),", tok2str(eap_type_values, "unknown", GET_U_1((cp + count))), @@ -211,6 +227,10 @@ eap_print(netdissect_options *ndo, case EAP_TYPE_TTLS: case EAP_TYPE_TLS: + if (len < 6) { + ND_PRINT(" (too short for EAP TLS/TTLS request/response)"); + return; + } if (subtype == EAP_TYPE_TTLS) ND_PRINT(" TTLSv%u", EAP_TTLS_VERSION(GET_U_1((cp + 5)))); @@ -219,11 +239,19 @@ eap_print(netdissect_options *ndo, GET_U_1(cp + 5)); if (EAP_TLS_EXTRACT_BIT_L(GET_U_1(cp + 5))) { + if (len < 10) { + ND_PRINT(" (too short for EAP TLS/TTLS request/response with length)"); + return; + } ND_PRINT(" len %u", GET_BE_U_4(cp + 6)); } break; case EAP_TYPE_FAST: + if (len < 6) { + ND_PRINT(" (too short for EAP FAST request/response)"); + return; + } ND_PRINT(" FASTv%u", EAP_TTLS_VERSION(GET_U_1((cp + 5)))); ND_PRINT(" flags [%s] 0x%02x,", @@ -231,6 +259,10 @@ eap_print(netdissect_options *ndo, GET_U_1(cp + 5)); if (EAP_TLS_EXTRACT_BIT_L(GET_U_1(cp + 5))) { + if (len < 10) { + ND_PRINT(" (too short for EAP FAST request/response with length)"); + return; + } ND_PRINT(" len %u", GET_BE_U_4(cp + 6)); } @@ -239,6 +271,10 @@ eap_print(netdissect_options *ndo, case EAP_TYPE_AKA: case EAP_TYPE_SIM: + if (len < 6) { + ND_PRINT(" (too short for EAP SIM/AKA request/response)"); + return; + } ND_PRINT(" subtype [%s] 0x%02x,", tok2str(eap_aka_subtype_values, "unknown", GET_U_1((cp + 5))), GET_U_1(cp + 5));