]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
CVE-2017-13022/IP: Add bounds checks to ip_printroute().
[tcpdump] / print-ip.c
index ccf61a3fcbac3224023c987d77319f5cecf4cf21..6831b7aa2d28acbb9c85519009c5017c6f1da400 100644 (file)
@@ -54,7 +54,7 @@ static const struct tok ip_option_values[] = {
 /*
  * print the recorded route in an IP RR, LSRR or SSRR option.
  */
-static void
+static int
 ip_printroute(netdissect_options *ndo,
               register const u_char *cp, u_int length)
 {
@@ -63,19 +63,25 @@ ip_printroute(netdissect_options *ndo,
 
        if (length < 3) {
                ND_PRINT((ndo, " [bad length %u]", length));
-               return;
+               return (0);
        }
        if ((length + 1) & 3)
                ND_PRINT((ndo, " [bad length %u]", length));
+       ND_TCHECK(cp[2]);
        ptr = cp[2] - 1;
        if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
                ND_PRINT((ndo, " [bad ptr %u]", cp[2]));
 
        for (len = 3; len < length; len += 4) {
+               ND_TCHECK2(cp[len], 4);
                ND_PRINT((ndo, " %s", ipaddr_string(ndo, &cp[len])));
                if (ptr > len)
                        ND_PRINT((ndo, ","));
        }
+       return (0);
+
+trunc:
+       return (-1);
 }
 
 /*
@@ -278,7 +284,8 @@ ip_optprint(netdissect_options *ndo,
                case IPOPT_RR:       /* fall through */
                case IPOPT_SSRR:
                case IPOPT_LSRR:
-                       ip_printroute(ndo, cp, option_len);
+                       if (ip_printroute(ndo, cp, option_len) == -1)
+                               goto trunc;
                        break;
 
                case IPOPT_RA: