From d00951bca056cd50c3e85d1ce8a66ae68be15710 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Sun, 19 May 2024 09:46:41 +0200 Subject: [PATCH] Fix recursive tcpedit cleanup Assume a single tcpedit struct and return the previously allocated context. This fixes an issue with the Juniper Encapsulated Ethernet DLT plugin which has an exception in the way the plugins works with regard to the extra buffer in question: tcpreplay works with the assumption that there only ever is a single link layer plugin which is mostly true except here: Juniper has a special call to tcpedit_dlt_copy_decoder_state() which causes the ctx and subctx to share a reference to the decoded_extra buffer, and a double free. Fixes: #813 #850 --- src/tcpedit/plugins/dlt_plugins.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tcpedit/plugins/dlt_plugins.c b/src/tcpedit/plugins/dlt_plugins.c index 51585378..1dc52ca1 100644 --- a/src/tcpedit/plugins/dlt_plugins.c +++ b/src/tcpedit/plugins/dlt_plugins.c @@ -94,6 +94,12 @@ 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: @@ -115,6 +121,9 @@ 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? */ @@ -443,6 +452,9 @@ tcpedit_dlt_cleanup(tcpeditdlt_t *ctx) { tcpeditdlt_plugin_t *plugin; + if (--tcpedit_dlt_is_initialized <= 0) + return; + assert(ctx); plugin = ctx->plugins;