X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/568d18f6eafb8df0d2500652b1cad49618051349..7b4e6191a77bdaff6f04af00b93eafb718b33662:/print-tcp.c diff --git a/print-tcp.c b/print-tcp.c index 0d62c4a9..142a2ba9 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -173,6 +173,7 @@ tcp_print(netdissect_options *ndo, uint16_t magic; int rev; const struct ip6_hdr *ip6; + u_int header_len; /* Header length in bytes */ ndo->ndo_protocol = "tcp"; tp = (const struct tcphdr *)bp; @@ -612,7 +613,7 @@ tcp_print(netdissect_options *ndo, break; case TCPOPT_MPTCP: - { + { const u_char *snapend_save; int ret; @@ -623,6 +624,13 @@ tcp_print(netdissect_options *ndo, * only do ND_TCHECK_LEN() if it returned 0. */ ND_TCHECK_LEN(cp, datalen); + /* Update the snapend to the end of the option + * before calling mptcp_print(). Some options + * (MPTCP or others) may be present after a + * MPTCP option. This prevents that, in + * mptcp_print(), the remaining length < the + * remaining caplen. + */ snapend_save = ndo->ndo_snapend; ndo->ndo_snapend = ND_MIN(cp - 2 + len, ndo->ndo_snapend); @@ -704,7 +712,17 @@ tcp_print(netdissect_options *ndo, /* * Decode payload if necessary. */ - bp += TH_OFF(tp) * 4; + header_len = TH_OFF(tp) * 4; + /* + * Do a bounds check before decoding the payload. + * At least the header data is required. + */ + if (!ND_TTEST_LEN(bp, header_len)) { + ND_PRINT(" [remaining caplen(%u) < header length(%u)]", + ND_BYTES_AVAILABLE_AFTER(bp), header_len); + nd_trunc_longjmp(ndo); + } + bp += header_len; if ((flags & TH_RST) && ndo->ndo_vflag) { print_tcp_rst_data(ndo, bp, length); return;