]> The Tcpdump Group git mirrors - tcpdump/commitdiff
DTP: improve packet integrity checks
authorDenis Ovsienko <[email protected]>
Sat, 5 Sep 2015 20:17:30 +0000 (21:17 +0100)
committerDenis Ovsienko <[email protected]>
Sat, 19 Sep 2015 19:32:27 +0000 (20:32 +0100)
Adjust the TLV infinite loop check to require the right amount of bytes
for T and L; do it after printing the TLV header so it is easier to
understand what was wrong. Check if the TLV V is within the capture. Use
the new "invalid" exit label to indicate a packet anomaly and add more
checks for the length value into the type-specific case blocks. Print
the domain string with fn_printzp().

print-dtp.c

index 3381ad80e0e7c4e52efe23499cc01259eb42caeb..4170cc7a80234777b3aa08d294ad51872e7a1c87 100644 (file)
@@ -27,6 +27,9 @@
 #include "addrtoname.h"
 #include "extract.h"
 
+static const char tstr[] = " [|dtp]";
+static const char istr[] = " (invalid)";
+
 #define DTP_HEADER_LEN                 1
 #define DTP_DOMAIN_TLV                 0x0001
 #define DTP_STATUS_TLV                 0x0002
@@ -70,30 +73,36 @@ dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length)
     while (tptr < (pptr+length)) {
 
         ND_TCHECK2(*tptr, 4);
-
        type = EXTRACT_16BITS(tptr);
         len  = EXTRACT_16BITS(tptr+2);
-
-        /* infinite loop check */
-        if (type == 0 || len == 0) {
+       /* XXX: should not be but sometimes it is, see the test captures */
+        if (type == 0)
             return;
-        }
-
         ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u",
                tok2str(dtp_tlv_values, "Unknown", type),
                type, len));
 
+        /* infinite loop check */
+        if (len < 4)
+            goto invalid;
+        ND_TCHECK2(*tptr, len);
+
         switch (type) {
        case DTP_DOMAIN_TLV:
-               ND_PRINT((ndo, ", %s", tptr+4));
+               ND_PRINT((ndo, ", "));
+               fn_printzp(ndo, tptr+4, len-4, pptr+length);
                break;
 
        case DTP_STATUS_TLV:
        case DTP_DTP_TYPE_TLV:
+                if (len < 5)
+                    goto invalid;
                 ND_PRINT((ndo, ", 0x%x", *(tptr+4)));
                 break;
 
        case DTP_NEIGHBOR_TLV:
+                if (len < 10)
+                    goto invalid;
                 ND_PRINT((ndo, ", %s", etheraddr_string(ndo, tptr+4)));
                 break;
 
@@ -105,8 +114,11 @@ dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length)
 
     return;
 
+ invalid:
+    ND_PRINT((ndo, "%s", istr));
+    return;
  trunc:
-    ND_PRINT((ndo, "[|dtp]"));
+    ND_PRINT((ndo, "%s", tstr));
 }
 
 /*