From: guy Date: Thu, 8 Jul 2004 10:29:40 +0000 (+0000) Subject: Check for a TCP header length that's too short, report more information X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/bfadcfe91ffc2584d00b6a9def079fa1e6b5cdfc Check for a TCP header length that's too short, report more information if it's too long, and check for NFS only if the header length is OK. --- diff --git a/print-tcp.c b/print-tcp.c index 6af150ca..82a714d3 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.107.2.3 2003-11-19 00:17:02 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.107.2.4 2004-07-08 10:29:40 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -212,11 +212,12 @@ tcp_print(register const u_char *bp, register u_int length, hlen = TH_OFF(tp) * 4; /* - * If data present and NFS port used, assume NFS. + * If data present, header length valid, and NFS port used, + * assume NFS. * Pass offset of data plus 4 bytes for RPC TCP msg length * to NFS print routines. */ - if (!qflag) { + if (!qflag && hlen >= sizeof(*tp) && hlen <= length) { if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend && dport == NFS_PORT) { nfsreq_print((u_char *)tp + hlen + 4, length - hlen, @@ -257,6 +258,12 @@ tcp_print(register const u_char *bp, register u_int length, } } + if (hlen < sizeof(*tp)) { + (void)printf(" tcp %d [bad hdr length %u - too short, < %u]", + length - hlen, hlen, sizeof(*tp)); + return; + } + TCHECK(*tp); seq = EXTRACT_32BITS(&tp->th_seq); @@ -265,7 +272,11 @@ tcp_print(register const u_char *bp, register u_int length, urp = EXTRACT_16BITS(&tp->th_urp); if (qflag) { - (void)printf("tcp %d", length - TH_OFF(tp) * 4); + (void)printf("tcp %d", length - hlen); + if (hlen > length) { + (void)printf(" [bad hdr length %u - too long, > %u]", + hlen, length); + } return; } if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH| @@ -391,7 +402,8 @@ tcp_print(register const u_char *bp, register u_int length, thseq = thack = threv = 0; } if (hlen > length) { - (void)printf(" [bad hdr length]"); + (void)printf(" [bad hdr length %u - too long, > %u]", + hlen, length); return; }