]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Add more checks.
authorGuy Harris <[email protected]>
Fri, 3 May 2019 18:11:58 +0000 (11:11 -0700)
committerGuy Harris <[email protected]>
Fri, 3 May 2019 18:11:58 +0000 (11:11 -0700)
Check that the payload specified in a Jumbo Payload option isn't smaller
than the total number of bytes worth of extension headers; if it is,
report truncation.

Check that:

1) we don't have more than one Jumbo Payload option;
2) we don't have a Jumbo Payload option if the payload length in the
IPv6 header was non-zero;
3) we don't have a Jumbo Payload option with a value < 65536.

print-ip6.c
print-ip6opts.c

index 2cc4e3090e35ece11633b58a99cf6e8b05cee5cc..15e13c2b4ed9dbc23a30b8b1425a127aa0f48a72 100644 (file)
@@ -413,8 +413,14 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
                                 * Set the length to the payload length
                                 * plus the IPv6 header length, and
                                 * change the snapshot length accordingly.
+                                *
+                                * But make sure it's not shorter than
+                                * the total number of bytes we've
+                                * processed so far.
                                 */
                                len = payload_len + sizeof(struct ip6_hdr);
+                               if (len < total_advance)
+                                       goto trunc;
                                if (length < len)
                                        ND_PRINT("truncated-ip6 - %u bytes missing!",
                                                len - length);
index 4039f44e32ca94cdd0bcde3bc81476f973f64b9a..8ef94faba199c47706740b3d00e284c1d2083926 100644 (file)
@@ -88,10 +88,12 @@ trunc:
 
 static int
 ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
-               int *found_jumbo, uint32_t *jumbolen)
+               int *found_jumbop, uint32_t *payload_len)
 {
     int i;
     int optlen = 0;
+    int found_jumbo = 0;
+    uint32_t jumbolen = 0;
 
     if (len == 0)
         return 0;
@@ -141,10 +143,32 @@ ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
                ND_PRINT("(jumbo: invalid len %u)", GET_U_1(bp + i + 1));
                goto trunc;
            }
-           *found_jumbo = 1;
-           *jumbolen = GET_BE_U_4(bp + i + 2);
-           if (ndo->ndo_vflag)
-               ND_PRINT("(jumbo: %u) ", *jumbolen);
+           jumbolen = GET_BE_U_4(bp + i + 2);
+           if (found_jumbo) {
+               /* More than one Jumbo Payload option */
+               if (ndo->ndo_vflag)
+                   ND_PRINT("(jumbo: %u - already seen) ", jumbolen);
+           } else {
+               found_jumbo = 1;
+               if (*payload_len != 0) {
+                   /* Payload length was non-zero - not valid */
+                   if (ndo->ndo_vflag)
+                       ND_PRINT("(jumbo: %u - payload len != 0) ", jumbolen);
+               } else {
+                   /* Payload length was zero in the IPv6 header */
+                   if (jumbolen < 65536) {
+                       /* Too short */
+                       if (ndo->ndo_vflag)
+                           ND_PRINT("(jumbo: %u - < 65536) ", jumbolen);
+                   } else {
+                       /* OK, this is valid */
+                       *found_jumbop = 1;
+                       *payload_len = jumbolen;
+                       if (ndo->ndo_vflag)
+                           ND_PRINT("(jumbo: %u) ", jumbolen);
+                   }
+               }
+           }
            break;
         case IP6OPT_HOME_ADDRESS:
            if (len - i < IP6OPT_HOMEADDR_MINLEN) {