]> The Tcpdump Group git mirrors - tcpdump/commitdiff
CVE-2017-13022/IP: Add bounds checks to ip_printroute().
authorGuy Harris <[email protected]>
Wed, 22 Mar 2017 06:07:17 +0000 (23:07 -0700)
committerDenis Ovsienko <[email protected]>
Sun, 3 Sep 2017 23:08:58 +0000 (00:08 +0100)
This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add a test using the capture file supplied by the reporter(s), modified
so the capture file won't be rejected as an invalid capture.

print-ip.c
tests/TESTLIST
tests/ip_printroute_asan.out [new file with mode: 0644]
tests/ip_printroute_asan.pcap [new file with mode: 0644]

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:
index 02bf5422079f2d594edc7f99c917810d7c7299e5..47a82769ee07d074f3b7cc5269049cf30fa603a9 100644 (file)
@@ -520,6 +520,7 @@ pgm_opts_asan               pgm_opts_asan.pcap              pgm_opts_asan.out       -v
 pgm_opts_asan_2                pgm_opts_asan_2.pcap            pgm_opts_asan_2.out     -v
 vtp_asan               vtp_asan.pcap                   vtp_asan.out    -v
 icmp6_mobileprefix_asan        icmp6_mobileprefix_asan.pcap    icmp6_mobileprefix_asan.out     -v
+ip_printroute_asan     ip_printroute_asan.pcap         ip_printroute_asan.out  -v
 
 # RTP tests
 # fuzzed pcap
diff --git a/tests/ip_printroute_asan.out b/tests/ip_printroute_asan.out
new file mode 100644 (file)
index 0000000..334973e
--- /dev/null
@@ -0,0 +1,2 @@
+IP (tos 0x0, ttl 254, id 25615, offset 65480, flags [DF, rsvd], proto UDP (17), length 32768, options (LSRR [bad length 25] [bad ptr 15] 103.103.103.0, 0.172.0.116, 0.16.36.36, 16.0.36.2 14.9.36.4[|ip]))
+    251.73.86.0 > 0.172.128.5: ip-proto-17
diff --git a/tests/ip_printroute_asan.pcap b/tests/ip_printroute_asan.pcap
new file mode 100644 (file)
index 0000000..379cd94
Binary files /dev/null and b/tests/ip_printroute_asan.pcap differ