X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/38b7ae42d148b79c121dd7032c2319b28b19f145..e69972a8ef1ddbf73924e42f76f53a1f9d0aab0a:/print-ip.c diff --git a/print-ip.c b/print-ip.c index 0f09b04e..23ba99c9 100644 --- a/print-ip.c +++ b/print-ip.c @@ -27,8 +27,6 @@ #include "netdissect-stdinc.h" -#include - #include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -53,7 +51,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, const u_char *cp, u_int length) { @@ -62,7 +60,7 @@ ip_printroute(netdissect_options *ndo, if (length < 3) { ND_PRINT(" [bad length %u]", length); - return; + return (0); } if ((length + 1) & 3) ND_PRINT(" [bad length %u]", length); @@ -71,10 +69,15 @@ ip_printroute(netdissect_options *ndo, ND_PRINT(" [bad ptr %u]", GET_U_1(cp + 2)); for (len = 3; len < length; len += 4) { + ND_TCHECK_4(cp + len); /* Needed to print the IP addresses */ ND_PRINT(" %s", GET_IPADDR_STRING(cp + len)); if (ptr > len) ND_PRINT(","); } + return (0); + +trunc: + return (-1); } /* @@ -273,7 +276,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: @@ -373,7 +377,10 @@ ip_print(netdissect_options *ndo, /* * Cut off the snapshot length to the end of the IP payload. */ - nd_push_snapend(ndo, bp + len); + if (!nd_push_snaplen(ndo, bp, len)) { + (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, + "%s: can't push snaplen on buffer stack", __func__); + } len -= hlen; @@ -467,8 +474,18 @@ ip_print(netdissect_options *ndo, GET_IPADDR_STRING(ip->ip_src), GET_IPADDR_STRING(ip->ip_dst)); } + /* + * Do a bounds check before calling ip_demux_print(). + * At least the header data is required. + */ + if (!ND_TTEST_LEN((const u_char *)ip, hlen)) { + ND_PRINT(" [remaining caplen(%u) < header length(%u)]", + ND_BYTES_AVAILABLE_AFTER((const u_char *)ip), + hlen); + nd_trunc_longjmp(ndo); + } ip_demux_print(ndo, (const u_char *)ip + hlen, len, 4, - off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp); + off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp); } else { /* * Ultra quiet now means that all this stuff should be @@ -496,7 +513,6 @@ ip_print(netdissect_options *ndo, trunc: nd_print_trunc(ndo); - return; } void