]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-isakmp.c
Handle very large -f files by rejecting them.
[tcpdump] / print-isakmp.c
index 9de9b75d21e74156a74f0708a5b2fa636861b803..951c8a74158b1b3369ee6375ded35f376c60199c 100644 (file)
@@ -912,21 +912,25 @@ struct attrmap {
 
 static const u_char *
 ikev1_attrmap_print(netdissect_options *ndo,
-                   const u_char *p, const u_char *ep,
+                   const u_char *p, const u_char *ep2,
                    const struct attrmap *map, size_t nmap)
 {
        int totlen;
        uint32_t t, v;
 
+       ND_TCHECK(p[0]);
        if (p[0] & 0x80)
                totlen = 4;
-       else
+       else {
+               ND_TCHECK_16BITS(&p[2]);
                totlen = 4 + EXTRACT_16BITS(&p[2]);
-       if (ep < p + totlen) {
+       }
+       if (ep2 < p + totlen) {
                ND_PRINT((ndo,"[|attr]"));
-               return ep + 1;
+               return ep2 + 1;
        }
 
+       ND_TCHECK_16BITS(&p[0]);
        ND_PRINT((ndo,"("));
        t = EXTRACT_16BITS(&p[0]) & 0x7fff;
        if (map && t < nmap && map[t].type)
@@ -935,47 +939,71 @@ ikev1_attrmap_print(netdissect_options *ndo,
                ND_PRINT((ndo,"type=#%d ", t));
        if (p[0] & 0x80) {
                ND_PRINT((ndo,"value="));
+               ND_TCHECK_16BITS(&p[2]);
                v = EXTRACT_16BITS(&p[2]);
                if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
                        ND_PRINT((ndo,"%s", map[t].value[v]));
-               else
-                       rawprint(ndo, (const uint8_t *)&p[2], 2);
+               else {
+                       if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
+                               ND_PRINT((ndo,")"));
+                               goto trunc;
+                       }
+               }
        } else {
-               ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
-               rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
+               ND_PRINT((ndo,"len=%d value=", totlen - 4));
+               if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
+                       ND_PRINT((ndo,")"));
+                       goto trunc;
+               }
        }
        ND_PRINT((ndo,")"));
        return p + totlen;
+
+trunc:
+       return NULL;
 }
 
 static const u_char *
-ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
+ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2)
 {
        int totlen;
        uint32_t t;
 
+       ND_TCHECK(p[0]);
        if (p[0] & 0x80)
                totlen = 4;
-       else
+       else {
+               ND_TCHECK_16BITS(&p[2]);
                totlen = 4 + EXTRACT_16BITS(&p[2]);
-       if (ep < p + totlen) {
+       }
+       if (ep2 < p + totlen) {
                ND_PRINT((ndo,"[|attr]"));
-               return ep + 1;
+               return ep2 + 1;
        }
 
+       ND_TCHECK_16BITS(&p[0]);
        ND_PRINT((ndo,"("));
        t = EXTRACT_16BITS(&p[0]) & 0x7fff;
        ND_PRINT((ndo,"type=#%d ", t));
        if (p[0] & 0x80) {
                ND_PRINT((ndo,"value="));
                t = p[2];
-               rawprint(ndo, (const uint8_t *)&p[2], 2);
+               if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
+                       ND_PRINT((ndo,")"));
+                       goto trunc;
+               }
        } else {
-               ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
-               rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
+               ND_PRINT((ndo,"len=%d value=", totlen - 4));
+               if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
+                       ND_PRINT((ndo,")"));
+                       goto trunc;
+               }
        }
        ND_PRINT((ndo,")"));
        return p + totlen;
+
+trunc:
+       return NULL;
 }
 
 static const u_char *
@@ -1256,11 +1284,12 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
        cp = (const u_char *)(p + 1);
        ep2 = (const u_char *)p + item_len;
        while (cp < ep && cp < ep2) {
-               if (map && nmap) {
-                       cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
-                               map, nmap);
-               } else
-                       cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+               if (map && nmap)
+                       cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
+               else
+                       cp = ikev1_attr_print(ndo, cp, ep2);
+               if (cp == NULL)
+                       goto trunc;
        }
        if (ep < ep2)
                ND_PRINT((ndo,"..."));
@@ -1284,6 +1313,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
        UNALIGNED_MEMCPY(&e, ext, sizeof(e));
        ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1406,8 +1436,8 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
                case IPSECDOI_ID_IPV6_ADDR_SUBNET:
                    {
                        const u_char *mask;
-                       if (len < 20)
-                               ND_PRINT((ndo," len=%d [bad: < 20]", len));
+                       if (len < 32)
+                               ND_PRINT((ndo," len=%d [bad: < 32]", len));
                        else {
                                mask = (const u_char *)(data + sizeof(struct in6_addr));
                                /*XXX*/
@@ -1486,6 +1516,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo," len=%d", item_len - 4));
        ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
        if (2 < ndo->ndo_vflag && 4 < item_len) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
                        goto trunc;
@@ -1518,6 +1549,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo," len=%d", item_len - 4));
        ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
        if (2 < ndo->ndo_vflag && 4 < item_len) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
                        goto trunc;
@@ -1542,6 +1574,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
        UNALIGNED_MEMCPY(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1566,6 +1599,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
        UNALIGNED_MEMCPY(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1724,14 +1758,18 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
                        size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
                        ND_PRINT((ndo," attrs=("));
                        while (cp < ep && cp < ep2) {
-                               cp = ikev1_attrmap_print(ndo, cp,
-                                       (ep < ep2) ? ep : ep2, map, nmap);
+                               cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
+                               if (cp == NULL) {
+                                       ND_PRINT((ndo,")"));
+                                       goto trunc;
+                               }
                        }
                        ND_PRINT((ndo,")"));
                        break;
                    }
                case IPSECDOI_NTYPE_REPLAY_STATUS:
                        ND_PRINT((ndo," status=("));
+                       ND_TCHECK_32BITS(cp);
                        ND_PRINT((ndo,"replay detection %sabled",
                                  EXTRACT_32BITS(cp) ? "en" : "dis"));
                        ND_PRINT((ndo,")"));
@@ -1818,6 +1856,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
        UNALIGNED_MEMCPY(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1852,6 +1891,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
 
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1926,10 +1966,11 @@ ikev2_t_print(netdissect_options *ndo, int tcount,
        ep2 = (const u_char *)p + item_len;
        while (cp < ep && cp < ep2) {
                if (map && nmap) {
-                       cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
-                               map, nmap);
+                       cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
                } else
-                       cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+                       cp = ikev1_attr_print(ndo, cp, ep2);
+               if (cp == NULL)
+                       goto trunc;
        }
        if (ep < ep2)
                ND_PRINT((ndo,"..."));
@@ -1989,7 +2030,6 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
                if (prop_length < sizeof(*ext))
                        goto toolong;
                ND_TCHECK(*ext);
-
                UNALIGNED_MEMCPY(&e, ext, sizeof(e));
 
                /*
@@ -2076,7 +2116,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
                if (sa_length < sizeof(*ext))
                        goto toolong;
                ND_TCHECK(*ext);
-
                UNALIGNED_MEMCPY(&e, ext, sizeof(e));
 
                /*
@@ -2137,7 +2176,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
        const struct ikev2_ke *k;
 
        k = (const struct ikev2_ke *)ext;
-       ND_TCHECK(*ext);
+       ND_TCHECK(*k);
        UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
        ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
 
@@ -2162,12 +2201,14 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
                uint32_t phase _U_, uint32_t doi _U_,
                uint32_t proto _U_, int depth _U_)
 {
+       const struct ikev2_id *idp;
        struct ikev2_id id;
        int id_len, idtype_len, i;
        unsigned int dumpascii, dumphex;
        const unsigned char *typedata;
 
-       ND_TCHECK(*ext);
+       idp = (const struct ikev2_id *)ext;
+       ND_TCHECK(*idp);
        UNALIGNED_MEMCPY(&id, ext, sizeof(id));
        ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
 
@@ -2175,6 +2216,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
 
        ND_PRINT((ndo," len=%d", id_len - 4));
        if (2 < ndo->ndo_vflag && 4 < id_len) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4))
                        goto trunc;
@@ -2270,7 +2312,7 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
        const u_char *authdata = (const u_char*)ext + sizeof(a);
        unsigned int len;
 
-       ND_TCHECK(*ext);
+       ND_TCHECK2(*ext, sizeof(a));
        UNALIGNED_MEMCPY(&a, ext, sizeof(a));
        ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
        len = ntohs(a.h.len);
@@ -2566,6 +2608,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
                else ND_PRINT((ndo, "."));
        }
        if (2 < ndo->ndo_vflag && 4 < len) {
+               /* Print the entire payload in hex */
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -2731,7 +2774,6 @@ ikev1_sub_print(netdissect_options *ndo,
 
        while (np) {
                ND_TCHECK(*ext);
-
                UNALIGNED_MEMCPY(&e, ext, sizeof(e));
 
                ND_TCHECK2(*ext, ntohs(e.len));
@@ -2899,7 +2941,6 @@ ikev2_sub_print(netdissect_options *ndo,
        cp = (const u_char *)ext;
        while (np) {
                ND_TCHECK(*ext);
-
                UNALIGNED_MEMCPY(&e, ext, sizeof(e));
 
                ND_TCHECK2(*ext, ntohs(e.len));