diff --git a/docs/CHANGELOG b/docs/CHANGELOG index 8aaa393b..71483a8a 100644 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -1,4 +1,5 @@ -09/03/2023 Version 4.5.0-beta1 +06/01/2024 Version 4.5.0-beta1 + - add check for IPv6 extension header length (#827 #842) - GitHub template for pull requests (#839) - handle IPv6 fragment extension header (#832 #837) - configure.ac: unify search dirs for pcap and add lib32 (#819) diff --git a/src/common/get.c b/src/common/get.c index ae3eaecd..1de06780 100644 --- a/src/common/get.c +++ b/src/common/get.c @@ -41,8 +41,8 @@ extern const char pcap_version[]; static void *get_ipv6_next(struct tcpr_ipv6_ext_hdr_base *exthdr, const u_char *end_ptr); /** - * Depending on what version of libpcap/WinPcap there are different ways to get - * the version of the libpcap/WinPcap library. This presents a unified way to + * Depending on what version of libpcap there are different ways to get + * the version of the libpcap library. This presents a unified way to * get that information. */ const char * @@ -196,8 +196,15 @@ parse_metadata(const u_char *pktdata, uint32_t *vlan_offset) { bool done = false; - int res = 0; - while (!done && res == 0) { + assert(next_protocol); + assert(l2len); + assert(l2offset); + assert(vlan_offset); + + if (!pktdata || !datalen) + errx(-1, "parse_metadata: invalid L2 parameters: pktdata=0x%p len=%d", pktdata, datalen); + + while (!done) { switch (*next_protocol) { case ETHERTYPE_VLAN: case ETHERTYPE_Q_IN_Q: @@ -205,18 +212,22 @@ parse_metadata(const u_char *pktdata, if (*vlan_offset == 0) *vlan_offset = *l2len; - res = parse_vlan(pktdata, datalen, next_protocol, l2len); + if (parse_vlan(pktdata, datalen, next_protocol, l2len)) + return -1; + break; case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MULTI: - res = parse_mpls(pktdata, datalen, next_protocol, l2len, l2offset); + if (parse_mpls(pktdata, datalen, next_protocol, l2len, l2offset)) + return -1; + break; default: done = true; } } - return res; + return 0; } /* @@ -629,9 +640,11 @@ get_layer4_v6(const ipv6_hdr_t *ip6_hdr, const u_char *end_ptr) * no further processing, either TCP, UDP, ICMP, etc... */ default: - if (proto != ip6_hdr->ip_nh) { + if (proto != ip6_hdr->ip_nh && next) { dbgx(3, "Returning byte offset of this ext header: %u", IPV6_EXTLEN_TO_BYTES(next->ip_len)); next = (void *)((u_char *)next + IPV6_EXTLEN_TO_BYTES(next->ip_len)); + if ((u_char*)next > end_ptr) + return NULL; } else { dbgx(3, "%s", "Returning end of IPv6 Header"); } @@ -687,6 +700,10 @@ get_ipv6_next(struct tcpr_ipv6_ext_hdr_base *exthdr, const u_char *end_ptr) case TCPR_IPV6_NH_HBH: case TCPR_IPV6_NH_AH: extlen = IPV6_EXTLEN_TO_BYTES(exthdr->ip_len); + if (extlen == 0) { + dbg(3, "Malformed IPv6 extension header..."); + return NULL; + } dbgx(3, "Looks like we're an ext header (0x%hhx). Jumping %u bytes" " to the next",