]> The Tcpdump Group git mirrors - tcpdump/commitdiff
EAP: add some more length checks.
authorGuy Harris <[email protected]>
Sun, 14 Nov 2021 02:50:02 +0000 (18:50 -0800)
committerGuy Harris <[email protected]>
Sun, 14 Nov 2021 02:50:02 +0000 (18:50 -0800)
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).

print-eap.c

index 42b22f625c733e1813e7b0a9e509ae80decc514f..04acccb2bf2a706272a6594d35f3f975ad94a369 100644 (file)
@@ -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));