]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-isoclns.c
CVE-2017-13040/MPTCP: Clean up printing DSS suboption.
[tcpdump] / print-isoclns.c
index 95339a0adc0ca5d48a2847553fab33beefe8ce39..6285502845247c95ac3bb999bb934ccf99a84d2b 100644 (file)
@@ -1217,10 +1217,18 @@ esis_print(netdissect_options *ndo,
                pptr += netal;
                 li -= netal;
 
-               if (netal == 0)
-                       ND_PRINT((ndo, "\n\t  %s", etheraddr_string(ndo, snpa)));
+               if (snpal == 6)
+                       ND_PRINT((ndo, "\n\t  SNPA (length: %u): %s",
+                              snpal,
+                              etheraddr_string(ndo, snpa)));
                else
-                       ND_PRINT((ndo, "\n\t  %s", isonsap_string(ndo, neta, netal)));
+                       ND_PRINT((ndo, "\n\t  SNPA (length: %u): %s",
+                              snpal,
+                              linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal)));
+               if (netal != 0)
+                       ND_PRINT((ndo, "\n\t  NET (length: %u) %s",
+                              netal,
+                              isonsap_string(ndo, neta, netal)));
                break;
        }
 
@@ -1395,6 +1403,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
 
   while (len > 2)
   {
+    ND_TCHECK2(*tptr, 2);
     stlv_type = *(tptr++);
     stlv_len  = *(tptr++);
 
@@ -1407,11 +1416,18 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
     /*len -= TLV_TYPE_LEN_OFFSET;*/
     len = len -2;
 
+    /* Make sure the subTLV fits within the space left */
+    if (len < stlv_len)
+      goto trunc;
+    /* Make sure the entire subTLV is in the captured data */
+    ND_TCHECK2(*(tptr), stlv_len);
+
     switch (stlv_type)
     {
       case ISIS_SUBTLV_SPB_MCID:
       {
-        ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN);
+       if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
+         goto trunc;
 
         subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
 
@@ -1426,15 +1442,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
 
           /*tptr += SPB_MCID_MIN_LEN;
             len -= SPB_MCID_MIN_LEN; */
-        tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
-        len = len - sizeof(struct isis_subtlv_spb_mcid);
+        tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+        len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
+        stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
 
         break;
       }
 
       case ISIS_SUBTLV_SPB_DIGEST:
       {
-        ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN);
+        if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
+          goto trunc;
 
         ND_PRINT((ndo, "\n\t        RES: %d V: %d A: %d D: %d",
                         (*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
@@ -1453,18 +1471,15 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
         }
 
         len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+        stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
 
         break;
       }
 
       case ISIS_SUBTLV_SPB_BVID:
       {
-        ND_TCHECK2(*(tptr), stlv_len);
-
-        while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
+        while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
         {
-          ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN);
-
           ND_PRINT((ndo, "\n\t           ECT: %08x",
                       EXTRACT_32BITS(tptr)));
 
@@ -1477,14 +1492,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
 
           tptr = tptr + 2;
           len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+          stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
         }
 
         break;
       }
 
       default:
-          break;
+        break;
     }
+    tptr += stlv_len;
+    len -= stlv_len;
   }
 
   return 0;
@@ -1503,6 +1521,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
 
   while (len > 2)
   {
+    ND_TCHECK2(*tptr, 2);
     stlv_type = *(tptr++);
     stlv_len  = *(tptr++);
 
@@ -1514,11 +1533,17 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
 
     len = len - 2;
 
+    /* Make sure the subTLV fits within the space left */
+    if (len < stlv_len)
+      goto trunc;
+    /* Make sure the entire subTLV is in the captured data */
+    ND_TCHECK2(*(tptr), stlv_len);
+
     switch (stlv_type)
     {
       case ISIS_SUBTLV_SPB_INSTANCE:
-
-          ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN);
+          if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
+            goto trunc;
 
           ND_PRINT((ndo, "\n\t        CIST Root-ID: %08x", EXTRACT_32BITS(tptr)));
           tptr = tptr+4;
@@ -1540,10 +1565,12 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
           tmp = *(tptr++);
 
           len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
+          stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
 
           while (tmp)
           {
-            ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN);
+            if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
+              goto trunc;
 
             ND_PRINT((ndo, "\n\t         U:%d, M:%d, A:%d, RES:%d",
                       *(tptr) >> 7, (*(tptr) >> 6) & 0x01,
@@ -1561,14 +1588,15 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
 
             tptr = tptr + 3;
             len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
+            stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
             tmp--;
           }
 
           break;
 
       case ISIS_SUBTLV_SPBM_SI:
-
-          ND_TCHECK2(*tptr, 8);
+          if (stlv_len < 8)
+            goto trunc;
 
           ND_PRINT((ndo, "\n\t        BMAC: %08x", EXTRACT_32BITS(tptr)));
           tptr = tptr+4;
@@ -1600,6 +1628,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
       default:
         break;
     }
+    tptr += stlv_len;
+    len -= stlv_len;
   }
   return 0;
 
@@ -1616,8 +1646,12 @@ isis_print_id(const uint8_t *cp, int id_len)
     int i;
     static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
     char *pos = id;
+    int sysid_len;
 
-    for (i = 1; i <= SYSTEM_ID_LEN; i++) {
+    sysid_len = SYSTEM_ID_LEN;
+    if (sysid_len > id_len)
+        sysid_len = id_len;
+    for (i = 1; i <= sysid_len; i++) {
         snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
        pos += strlen(pos);
        if (i == 2 || i == 4)
@@ -2038,7 +2072,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo,
         }
         processed++;
     } else if (afi == AF_INET6) {
-        if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
+        if (!ND_TTEST2(*tptr, 2)) /* fetch status & prefix_len byte */
             return (0);
         status_byte=*(tptr++);
         bit_length=*(tptr++);
@@ -2532,6 +2566,7 @@ isis_print(netdissect_options *ndo,
            ND_TCHECK2(*tptr, 1);
            alen = *tptr++;
            while (tmp && alen < tmp) {
+               ND_TCHECK2(*tptr, alen);
                ND_PRINT((ndo, "\n\t      Area address (length: %u): %s",
                        alen,
                        isonsap_string(ndo, tptr, alen)));