diff --git a/.github/workflows/github-actions-ci.yml b/.github/workflows/github-actions-ci.yml index 8a9882d5..1b81f614 100644 --- a/.github/workflows/github-actions-ci.yml +++ b/.github/workflows/github-actions-ci.yml @@ -18,7 +18,7 @@ jobs: - name: Create configure script run: ./autogen.sh - name: configure - run: ./configure --with-testnic=eth0 --disable-local-libopts + run: ./configure --with-testnic=eth0 --disable-local-libopts --enable-asan - name: make run: make - name: make dist diff --git a/docs/CHANGELOG b/docs/CHANGELOG index c918319a..0dddb539 100644 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -1,5 +1,7 @@ -06/02/2024 Version 4.5.0-beta1 - - fix nansecond timestamp regression bug (#863) +06/08/2024 Version 4.5.0-beta1 + - memory leak in tcpprep when using include/exclude (#869) + - memory leak in tcpprep when using RegEx (#867) + - fix nanosecond timestamp regression bug (#863) - autotools - AC_HELP_STRING is obsolete in 2.70 (#856) - configure.ac: do not run conftest in case of cross compilation (#849) - Haiku support (#847) @@ -8,20 +10,26 @@ - add check for IPv6 extension header length (#827 #842) - GitHub template for pull requests (#839) - handle IPv6 fragment extension header (#832 #837) + - Linux tap interfaces fail intermittently (#828) - Infinite loop in tcprewrite at get.c (#827 #842) - - add check for empty CIDR (#824 #843) + - SLL incorrect size and protocol when converted to Ethernet (#826) + - CVE-2023-43279 add check for empty CIDR (#824 #843) - AF_XDF socket extension (#822 #823) - configure.ac: unify search dirs for pcap and add lib32 (#819) - - double free in tcpedit_dlt_cleanup in tcprewrite (#813 #855) + - tcpreplay-edit recomputes IPv4 checksums unnecessarily (#815 #846) + - CVE-2023-4256 double free in tcprewrite DLT_JUNIPER_ETHER (#813 #851) - dlt_jnpr_ether_cleanup: check config before cleanup (#812 #851) - - nanosecond timestamps (#796) + - SEGV on invalid Juniper Ethernet header length (#811) + - nanosecond timestamps support (#796) + - Linux cooked packet fatal error (#792) - low PPS values run at full speed after several days (#779) - create DLT_LINUX_SLL2 plugin (#727) 06/04/2023 Version 4.4.4 - overflow check fix for parse_mpls (#795) - tcpreplay-edit: prevent L2 flooding of ipv6 unicast packets (#793) - - CVE-2023-27786 bugs caused by strtok_r (#782 #784 #785 #786 #787 #788) + - CVE-2023-27784 CVE-2023-27785 CVE-2023-27786 CVE-2023-27787 CVE-2023-27788 CVE-2023-27789 + bugs caused by strtok_r (#782 #784 #785 #786 #787 #788) - CVE-2023-27783 reachable assert in tcpedit_dlt_cleanup (#780) - add CI and C/C++ Linter and CodeQL (#773) - reachable assert in fast_edit_packet (#772) @@ -53,15 +61,16 @@ - build failures Debian/kfreebsd (#706) - bus error when building on armhf (#705) - typo fixes (#704) - - heap buffer overflow in tcpreplay (#703) - - double free in Juniper DLT (#702) + - CVE-2022-27418 heap buffer overflow in tcpreplay (#703) + - CVE-2022-27416 double free in Juniper DLT (#702) 01/31/2022 Version 4.4.0 - remove obsolete FORCE_ALIGN support to fix macOS 11 compile (#695) - add a security policy document (#689) + - CVE-2021-45386 CVE-2021-45387 two reachable assertions in add_tree_ipv4() and add_tree_ipv6() (#687 #678) - ability to specify directory of pcap files (#682) - incorrect PPS rate for long-running sessions (#679) - - option --skipbroadcast not working (#677) + - option --skipbroadcast not working (#677 #678) - revert #630 to fix --multiplier issues (#674) - gcc 9.3 compiler warnings (#670) - installed netmap not automatically detected (#669) @@ -100,7 +109,7 @@ - CVE-2018-20553 Correct L2 header length calculations so that IP header offset is correct (#584) - Correct L2 header length to correct IP header offset (#583) - Fix warnings from gcc version 10 (#580) - - Heap Buffer Overflow in randomize_iparp (#579) + - CVE-2020-23273 Heap Buffer Overflow in randomize_iparp (#579) - Use after free in get_ipv6_next (#578) - CVE-2020-12740 Heap Buffer Overflow in git_ipv6_next (#576) - Call pcap_freecode() on pcap_compile() (#572) @@ -108,7 +117,7 @@ - Fix divide by zero in fuzzing (#570) - Unique IP repeats at very high iteration counts (#566) - Fails to compile on FreeBSD amd64 13.0 (#558) - - Heap Buffer Overflow in do_checksum (#556) (#577) + - CVE-2020-18976 Heap Buffer Overflow in do_checksum (#556) (#577) - Attempt to correct corrupt pcap files, if possible (#557) - Fix GCC v10 warnings (#555) - Remove some duplicated SOURCES entries (#551) diff --git a/src/common/sendpacket.c b/src/common/sendpacket.c index 6b060aad..11e3a761 100644 --- a/src/common/sendpacket.c +++ b/src/common/sendpacket.c @@ -524,10 +524,6 @@ sendpacket_open(const char *device, sendpacket_type_t sendpacket_type _U_, void *arg _U_) { -#ifdef HAVE_TUNTAP - char sys_dev_dir[128]; - bool device_exists; -#endif sendpacket_t *sp; struct stat sdata; @@ -536,11 +532,6 @@ sendpacket_open(const char *device, errbuf[0] = '\0'; -#ifdef HAVE_TUNTAP - snprintf(sys_dev_dir, sizeof(sys_dev_dir), "/sys/class/net/%s/", device); - device_exists = access(sys_dev_dir, R_OK) == 0; -#endif - /* khial is universal */ if (stat(device, &sdata) == 0) { if (((sdata.st_mode & S_IFMT) == S_IFCHR)) { @@ -563,7 +554,7 @@ sendpacket_open(const char *device, } } #ifdef HAVE_TUNTAP - } else if (strncmp(device, "tap", 3) == 0 && !device_exists) { + } else if (strncmp(device, "tap", 3) == 0) { sp = sendpacket_open_tuntap(device, errbuf); #endif } else { @@ -895,9 +886,12 @@ sendpacket_open_tuntap(const char *device, char *errbuf) strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name) - 1); if (ioctl(tapfd, TUNSETIFF, (void *)&ifr) < 0) { - snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to create tuntap interface: %s", device); - close(tapfd); - return NULL; + // ignore EBUSY - it just means that the tunnel has already been opened + if (errno != EBUSY) { + snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to create tuntap interface: %s errno=%d", device, errno); + close(tapfd); + return NULL; + } } #elif defined(HAVE_FREEBSD) if (*device == '/') { diff --git a/src/tcpedit/plugins/dlt_en10mb/en10mb.c b/src/tcpedit/plugins/dlt_en10mb/en10mb.c index 957ce20d..3fbca624 100644 --- a/src/tcpedit/plugins/dlt_en10mb/en10mb.c +++ b/src/tcpedit/plugins/dlt_en10mb/en10mb.c @@ -519,9 +519,9 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir) } /* newl2len for some other DLT -> ethernet */ - else if (config->vlan == TCPEDIT_VLAN_ADD) { - /* if add a vlan then 18, */ - newl2len = TCPR_802_1Q_H; + else { + newl2len = config->vlan == TCPEDIT_VLAN_ADD ? TCPR_802_1Q_H : TCPR_802_3_H; + oldl2len = ctx->l2len; } if ((uint32_t)pktlen < newl2len || pktlen + newl2len - ctx->l2len > MAXPACKET) { @@ -555,7 +555,6 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir) /* update the total packet length */ pktlen += (int)(newl2len - oldl2len); - ctx->l2len += (int)(newl2len - oldl2len); /* set the src & dst address as the first 12 bytes */ eth = (struct tcpr_ethernet_hdr *)(packet + ctx->l2offset); @@ -665,6 +664,11 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir) } } + if (newl2len == TCPR_802_3_H) { + /* all we need for 802.3 is the proto */ + eth->ether_type = ctx->proto; + } + if (config->vlan == TCPEDIT_VLAN_ADD || (config->vlan == TCPEDIT_VLAN_OFF && extra->vlan)) { vlan_hdr = (struct tcpr_802_1q_hdr *)(packet + extra->vlan_offset); if (config->vlan == TCPEDIT_VLAN_ADD) { @@ -812,7 +816,7 @@ dlt_en10mb_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char *i if (l2len == -1 || pktlen < l2len) return NULL; - assert(ctx->decoded_extra_size == sizeof(*extra)); + assert(ctx->decoded_extra_size >= sizeof(*extra)); extra = (en10mb_extra_t *)ctx->decoded_extra; eth = (struct tcpr_ethernet_hdr *)(packet + ctx->l2offset); assert(eth); diff --git a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c index 9642a2c2..f5cd73b0 100644 --- a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c +++ b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c @@ -64,9 +64,7 @@ dlt_jnpr_ether_register(tcpeditdlt_t *ctx) plugin = tcpedit_dlt_newplugin(); plugin->provides += PLUGIN_MASK_PROTO + PLUGIN_MASK_SRCADDR + PLUGIN_MASK_DSTADDR; - plugin-> - requires - = 0; + plugin->requires = 0; /* what is our DLT value? */ plugin->dlt = dlt_value; @@ -304,6 +302,13 @@ dlt_jnpr_ether_proto(tcpeditdlt_t *ctx, const u_char *packet, int pktlen) memcpy(&jnpr_hdr_len, &packet[JUNIPER_ETHER_EXTLEN_OFFSET], 2); jnpr_hdr_len = ntohs(jnpr_hdr_len) + JUNIPER_ETHER_HEADER_LEN; + if (jnpr_hdr_len > pktlen) { + tcpedit_seterr(ctx->tcpedit, + "Juniper header length %d invalid: it is greater than packet length %d", + jnpr_hdr_len, pktlen); + return TCPEDIT_ERROR; + } + ethernet = packet + jnpr_hdr_len; /* let the en10mb plugin do the rest of the work */ diff --git a/src/tcpedit/plugins/dlt_plugins.c b/src/tcpedit/plugins/dlt_plugins.c index 5c2741c2..70885309 100644 --- a/src/tcpedit/plugins/dlt_plugins.c +++ b/src/tcpedit/plugins/dlt_plugins.c @@ -96,12 +96,6 @@ const char *tcpeditdlt_bit_info[] = {"Missing required Layer 3 protocol.", * Public functions ********************************************************************/ -/* - * Ensure init/cleanup are called only once - * Assume a single tcpedit struct and return the previously allocated context. - */ -static int tcpedit_dlt_is_initialized = 0; - /** * initialize our plugin library. Pass the DLT of the source pcap handle. * Actions: @@ -123,9 +117,6 @@ tcpedit_dlt_init(tcpedit_t *tcpedit, const int srcdlt) assert(tcpedit); assert(srcdlt >= 0); - if (tcpedit_dlt_is_initialized++ > 0) - return tcpedit->dlt_ctx; - ctx = (tcpeditdlt_t *)safe_malloc(sizeof(tcpeditdlt_t)); /* do we need a side buffer for L3 data? */ @@ -454,9 +445,6 @@ tcpedit_dlt_cleanup(tcpeditdlt_t *ctx) { tcpeditdlt_plugin_t *plugin; - if (--tcpedit_dlt_is_initialized <= 0) - return; - assert(ctx); plugin = ctx->plugins; diff --git a/src/tcpprep_api.c b/src/tcpprep_api.c index 2a9709eb..25f9a851 100644 --- a/src/tcpprep_api.c +++ b/src/tcpprep_api.c @@ -91,6 +91,14 @@ tcpprep_close(tcpprep_t *ctx) cidr = cidr_nxt; } + if (options->xX.list) + free_list(options->xX.list); + + if (options->xX.cidr) + safe_free(options->xX.cidr); + + regfree(&options->preg); + safe_free(options); safe_free(ctx->outfile);