]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-icmp.c
CVE-2017-13029/PPP: Fix a bounds check, and clean up other bounds checks.
[tcpdump] / print-icmp.c
index 7609fc0c8001df7dad2d4492dfda822a0870b5a9..366094eff829c08e519017334fdaa656ce40e333 100644 (file)
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/* \summary: Internet Control Message Protocol (ICMP) printer */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -479,7 +481,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
                            " [size %d]", size);
                        break;
                }
-               idp = (struct id_rdiscovery *)&dp->icmp_data;
+               idp = (const struct id_rdiscovery *)&dp->icmp_data;
                while (num-- > 0) {
                        ND_TCHECK(*idp);
                        (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}",
@@ -578,8 +580,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
                bp += 8;
                ND_PRINT((ndo, "\n\t"));
                ip = (const struct ip *)bp;
-               ndo->ndo_snaplen = ndo->ndo_snapend - bp;
                 snapend_save = ndo->ndo_snapend;
+               ND_TCHECK_16BITS(&ip->ip_len);
                ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len));
                 ndo->ndo_snapend = snapend_save;
        }
@@ -597,8 +599,9 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
              * to check if an extension header is present. This is expedient,
              * however not all implementations set the length field proper.
              */
-            if (!ext_dp->icmp_length) {
-                vec[0].ptr = (const uint8_t *)(void *)&ext_dp->icmp_ext_version_res;
+            if (!ext_dp->icmp_length &&
+                ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) {
+                vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
                 vec[0].len = plen - ICMP_EXTD_MINLEN;
                 if (in_cksum(vec, 1)) {
                     return;
@@ -618,12 +621,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
             }
 
             hlen = plen - ICMP_EXTD_MINLEN;
-            vec[0].ptr = (const uint8_t *)(void *)&ext_dp->icmp_ext_version_res;
-            vec[0].len = hlen;
-            ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
-                   EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
-                   in_cksum(vec, 1) ? "in" : "",
-                   hlen));
+            if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) {
+                vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
+                vec[0].len = hlen;
+                ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
+                       EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
+                       in_cksum(vec, 1) ? "in" : "",
+                       hlen));
+            }
 
             hlen -= 4; /* subtract common header size */
             obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data;