]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-tcp.c
CVE-2016-7931/Add bounds and length checks.
[tcpdump] / print-tcp.c
index 043d9b671bf05dfc17b358fe30b36479764dad50..f00ff32514802bebf9dd4ad8df20b300ffeb873a 100644 (file)
@@ -23,6 +23,8 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/* \summary: TCP printer */
+
 #ifndef lint
 #else
 __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
@@ -187,8 +189,6 @@ tcp_print(netdissect_options *ndo,
         sport = EXTRACT_16BITS(&tp->th_sport);
         dport = EXTRACT_16BITS(&tp->th_dport);
 
-        hlen = TH_OFF(tp) * 4;
-
         if (ip6) {
                 if (ip6->ip6_nxt == IPPROTO_TCP) {
                         ND_PRINT((ndo, "%s.%s > %s.%s: ",
@@ -213,14 +213,16 @@ tcp_print(netdissect_options *ndo,
                 }
         }
 
+        ND_TCHECK(*tp);
+
+        hlen = TH_OFF(tp) * 4;
+
         if (hlen < sizeof(*tp)) {
                 ND_PRINT((ndo, " tcp %d [bad hdr length %u - too short, < %lu]",
                              length - hlen, hlen, (unsigned long)sizeof(*tp)));
                 return;
         }
 
-        ND_TCHECK(*tp);
-
         seq = EXTRACT_32BITS(&tp->th_seq);
         ack = EXTRACT_32BITS(&tp->th_ack);
         win = EXTRACT_16BITS(&tp->th_win);
@@ -462,7 +464,7 @@ tcp_print(netdissect_options *ndo,
                         case TCPOPT_SACK:
                                 datalen = len - 2;
                                 if (datalen % 8 != 0) {
-                                        ND_PRINT((ndo, "invalid sack"));
+                                        ND_PRINT((ndo, " invalid sack"));
                                 } else {
                                         uint32_t s, e;
 
@@ -510,6 +512,7 @@ tcp_print(netdissect_options *ndo,
                         case TCPOPT_SIGNATURE:
                                 datalen = TCP_SIGLEN;
                                 LENCHECK(datalen);
+                                ND_PRINT((ndo, " "));
 #ifdef HAVE_LIBCRYPTO
                                 switch (tcp_verify_signature(ndo, ip, tp,
                                                              bp + TH_OFF(tp) * 4, length, cp)) {
@@ -535,10 +538,10 @@ tcp_print(netdissect_options *ndo,
                                 break;
 
                         case TCPOPT_AUTH:
-                                ND_PRINT((ndo, "keyid %d", *cp++));
+                                ND_PRINT((ndo, " keyid %d", *cp++));
                                 datalen = len - 3;
                                 for (i = 0; i < datalen; ++i) {
-                                        LENCHECK(i);
+                                        LENCHECK(i + 1);
                                         ND_PRINT((ndo, "%02x", cp[i]));
                                 }
                                 break;
@@ -557,7 +560,7 @@ tcp_print(netdissect_options *ndo,
                                 datalen = 2;
                                 LENCHECK(datalen);
                                 utoval = EXTRACT_16BITS(cp);
-                                ND_PRINT((ndo, "0x%x", utoval));
+                                ND_PRINT((ndo, " 0x%x", utoval));
                                 if (utoval & 0x0001)
                                         utoval = (utoval >> 1) * 60;
                                 else
@@ -575,6 +578,7 @@ tcp_print(netdissect_options *ndo,
                         case TCPOPT_FASTOPEN:
                                 datalen = len - 2;
                                 LENCHECK(datalen);
+                                ND_PRINT((ndo, " "));
                                 print_tcp_fastopen_option(ndo, cp, datalen, FALSE);
                                 break;
 
@@ -605,7 +609,7 @@ tcp_print(netdissect_options *ndo,
                                 if (datalen)
                                         ND_PRINT((ndo, " 0x"));
                                 for (i = 0; i < datalen; ++i) {
-                                        LENCHECK(i);
+                                        LENCHECK(i + 1);
                                         ND_PRINT((ndo, "%02x", cp[i]));
                                 }
                                 break;