From: Guy Harris Date: Mon, 10 Nov 2014 07:24:53 +0000 (-0800) Subject: Use ND_TCHECK() to do bounds checking. X-Git-Tag: tcpdump-4.7.0-bp~9 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/9ed7ddb48fd557dc993e73f22a50dda6cedf4df7 Use ND_TCHECK() to do bounds checking. While we're at it, just use the record count to when iterating over records; the ND_TCHECK()s will make sure we don't run past the end of the captured data. Also get rid of an unused argument to cnfp_print(). --- diff --git a/netdissect.h b/netdissect.h index a554eae2..7d7bfa1c 100644 --- a/netdissect.h +++ b/netdissect.h @@ -478,7 +478,7 @@ extern u_int atm_if_print(netdissect_options *, const struct pcap_pkthdr *, cons extern void vtp_print(netdissect_options *, const u_char *, u_int); extern int mptcp_print(netdissect_options *, const u_char *, u_int, u_char); extern void ntp_print(netdissect_options *, const u_char *, u_int); -extern void cnfp_print(netdissect_options *, const u_char *, const u_char *); +extern void cnfp_print(netdissect_options *, const u_char *); extern void dvmrp_print(netdissect_options *, const u_char *, u_int); extern void egp_print(netdissect_options *, const u_char *, u_int); extern u_int enc_if_print(netdissect_options *, const struct pcap_pkthdr *, const u_char *); diff --git a/print-cnfp.c b/print-cnfp.c index 07c940cb..9f3eefae 100644 --- a/print-cnfp.c +++ b/print-cnfp.c @@ -75,8 +75,7 @@ struct nfrec { }; void -cnfp_print(netdissect_options *ndo, - const u_char *cp, const u_char *bp _U_) +cnfp_print(netdissect_options *ndo, const u_char *cp) { register const struct nfhdr *nh; register const struct nfrec *nr; @@ -87,9 +86,7 @@ cnfp_print(netdissect_options *ndo, #endif nh = (const struct nfhdr *)cp; - - if ((const u_char *)(nh + 1) > ndo->ndo_snapend) - return; + ND_TCHECK(*nh); nrecs = EXTRACT_32BITS(&nh->ver_cnt) & 0xffff; ver = (EXTRACT_32BITS(&nh->ver_cnt) & 0xffff0000) >> 16; @@ -110,18 +107,23 @@ cnfp_print(netdissect_options *ndo, if (ver == 5 || ver == 6) { ND_PRINT((ndo, "#%u, ", EXTRACT_32BITS(&nh->sequence))); nr = (const struct nfrec *)&nh[1]; - ndo->ndo_snaplen -= 24; - } else { + } else nr = (const struct nfrec *)&nh->sequence; - ndo->ndo_snaplen -= 16; - } ND_PRINT((ndo, "%2u recs", nrecs)); - for (; nrecs-- && (const u_char *)(nr + 1) <= ndo->ndo_snapend; nr++) { + for (; nrecs != 0; nr++, nrecs--) { char buf[20]; char asbuf[20]; + /* + * Make sure we have the entire record. + */ + if (ver == 5 || ver == 6) { + ND_TCHECK(nr->masks); + } else { + ND_TCHECK(nr->proto_tos); + } ND_PRINT((ndo, "\n started %u.%03u, last %u.%03u", EXTRACT_32BITS(&nr->start_time)/1000, EXTRACT_32BITS(&nr->start_time)%1000, @@ -184,4 +186,9 @@ cnfp_print(netdissect_options *ndo, EXTRACT_32BITS(&nr->packets), EXTRACT_32BITS(&nr->octets), buf)); } + return; + +trunc: + ND_PRINT((ndo, "[|cnfp]")); + return; } diff --git a/print-udp.c b/print-udp.c index eafdaf88..52be99c3 100644 --- a/print-udp.c +++ b/print-udp.c @@ -444,7 +444,7 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length, case PT_CNFP: udpipaddr_print(ndo, ip, sport, dport); - cnfp_print(ndo, cp, (const u_char *)ip); + cnfp_print(ndo, cp); break; case PT_TFTP: