From 523e89815e724efc480feb2e7b93303e871e35ff Mon Sep 17 00:00:00 2001 From: Fred Klassen Date: Mon, 26 Apr 2021 16:57:50 -0700 Subject: [PATCH] Bug #582 fix plugin cleanups to fix memory leaks --- docs/CHANGELOG | 1 + src/common/list.c | 5 +- src/common/services.c | 1 + src/tcpbridge.c | 8 ++- src/tcpedit/plugins/dlt_en10mb/en10mb.c | 54 +++++++++++----- src/tcpedit/plugins/dlt_hdlc/hdlc.c | 33 +++++++--- src/tcpedit/plugins/dlt_ieee80211/ieee80211.c | 33 +++++++--- src/tcpedit/plugins/dlt_linuxsll/linuxsll.c | 33 +++++++--- src/tcpedit/plugins/dlt_plugins.c | 18 +++++- src/tcpedit/plugins/dlt_radiotap/radiotap.c | 33 +++++++--- src/tcpedit/plugins/dlt_raw/raw.c | 34 ++++++---- src/tcpedit/plugins/dlt_user/user.c | 33 +++++++--- src/tcpedit/portmap.c | 8 +-- src/tcpedit/tcpedit.c | 64 +++++++++++++++++-- src/tcpedit/tcpedit.h | 2 +- src/tcpedit/tcpedit_types.h | 1 - src/tcpreplay.c | 8 +++ src/tcprewrite.c | 21 ++++-- 18 files changed, 294 insertions(+), 96 deletions(-) diff --git a/docs/CHANGELOG b/docs/CHANGELOG index 2f96b8d96..b38294898 100644 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -16,6 +16,7 @@ - fix UNUSED macro declaration (#614) - handle malformed and unsupported packets as soft errors (#613) - compile failure on aarch64-linux-android (#612) + - tcprewrite --fixlen not working (#582) - fix configure --without-libdnet (#567) - ensure automake version is at least 1.15 (#553) - with multiplier option only first file can be sent and hang (#472) diff --git a/src/common/list.c b/src/common/list.c index 467c7027b..81f71399a 100644 --- a/src/common/list.c +++ b/src/common/list.c @@ -80,10 +80,10 @@ parse_list(tcpr_list_t ** listdata, char *ourstr) /* regex test */ if (regexec(&preg, this, 0, NULL, 0) != 0) { warnx("Unable to parse: %s", this); + regfree(&preg); return 0; } - *listdata = new_list(); list_ptr = *listdata; listcur = list_ptr; @@ -115,6 +115,7 @@ parse_list(tcpr_list_t ** listdata, char *ourstr) /* regex test */ if (regexec(&preg, this, 0, NULL, 0) != 0) { warnx("Unable to parse: %s", this); + regfree(&preg); return 0; } @@ -138,6 +139,8 @@ parse_list(tcpr_list_t ** listdata, char *ourstr) } + regfree(&preg); + return 1; } diff --git a/src/common/services.c b/src/common/services.c index fe2aed098..7e78ed678 100644 --- a/src/common/services.c +++ b/src/common/services.c @@ -91,5 +91,6 @@ parse_services(const char *file, tcpr_services_t *services) } } + regfree(&preg); fclose(service); } diff --git a/src/tcpbridge.c b/src/tcpbridge.c index 16baa5c1d..1061c2aa2 100644 --- a/src/tcpbridge.c +++ b/src/tcpbridge.c @@ -79,12 +79,14 @@ main(int argc, char *argv[]) /* parse the tcpedit args */ rcode = tcpedit_post_args(tcpedit); if (rcode < 0) { + tcpedit_close(&tcpedit); errx(-1, "Unable to parse args: %s", tcpedit_geterr(tcpedit)); } else if (rcode == 1) { warnx("%s", tcpedit_geterr(tcpedit)); } if (tcpedit_validate(tcpedit) < 0) { + tcpedit_close(&tcpedit); errx(-1, "Unable to edit packets given options:\n%s", tcpedit_geterr(tcpedit)); } @@ -96,9 +98,10 @@ main(int argc, char *argv[]) } #endif - if (gettimeofday(&stats.start_time, NULL) < 0) + if (gettimeofday(&stats.start_time, NULL) < 0) { + tcpedit_close(&tcpedit); err(-1, "gettimeofday() failed"); - + } /* process packets */ do_bridge(&options, tcpedit); @@ -110,6 +113,7 @@ main(int argc, char *argv[]) pcap_close(options.pcap2); } + tcpedit_close(&tcpedit); #ifdef ENABLE_VERBOSE tcpdump_close(options.tcpdump); #endif diff --git a/src/tcpedit/plugins/dlt_en10mb/en10mb.c b/src/tcpedit/plugins/dlt_en10mb/en10mb.c index d27cb4162..6983731cc 100644 --- a/src/tcpedit/plugins/dlt_en10mb/en10mb.c +++ b/src/tcpedit/plugins/dlt_en10mb/en10mb.c @@ -104,8 +104,17 @@ dlt_en10mb_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - ctx->decoded_extra_size = sizeof(en10mb_extra_t); - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < sizeof(en10mb_extra_t)) { + ctx->decoded_extra_size = sizeof(en10mb_extra_t); + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = sizeof(en10mb_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } + plugin->config_size = sizeof(en10mb_config_t); plugin->config = safe_malloc(plugin->config_size); config = (en10mb_config_t *)plugin->config; @@ -128,11 +137,28 @@ int dlt_en10mb_cleanup(tcpeditdlt_t *ctx) { tcpeditdlt_plugin_t *plugin; - + assert(ctx); - - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) - return TCPEDIT_OK; + + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); + return TCPEDIT_ERROR; + } + + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + if (plugin->config) { + en10mb_config_t *config = (en10mb_config_t*)plugin->config; + safe_free(config->subs.entries); + safe_free(plugin->config); + } + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); @@ -140,12 +166,6 @@ dlt_en10mb_cleanup(tcpeditdlt_t *ctx) ctx->decoded_extra_size = 0; } - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } - return TCPEDIT_OK; /* success */ } @@ -164,14 +184,16 @@ en10mb_sub_entry_t * dlt_en10mb_realloc_merge(en10mb_sub_conf_t config, en10mb_sub_entry_t *new_entries, int entries_count) { int i; - en10mb_sub_entry_t *merged = safe_realloc( - config.entries, (config.count + entries_count) * sizeof(en10mb_sub_entry_t)); + + config.entries = safe_realloc(config.entries, + (config.count + entries_count) + * sizeof(en10mb_sub_entry_t)); for (i = 0; i < entries_count; i++) { - merged[config.count + i] = new_entries[i]; + config.entries[config.count + i] = new_entries[i]; } - return merged; + return config.entries; } int diff --git a/src/tcpedit/plugins/dlt_hdlc/hdlc.c b/src/tcpedit/plugins/dlt_hdlc/hdlc.c index 2f743e481..896bdf347 100644 --- a/src/tcpedit/plugins/dlt_hdlc/hdlc.c +++ b/src/tcpedit/plugins/dlt_hdlc/hdlc.c @@ -102,8 +102,16 @@ dlt_hdlc_init(tcpeditdlt_t *ctx) } /* allocate memory for our deocde extra data */ - ctx->decoded_extra_size = sizeof(hdlc_extra_t); - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < sizeof(hdlc_extra_t)) { + ctx->decoded_extra_size = sizeof(hdlc_extra_t); + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = sizeof(hdlc_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } /* allocate memory for our config data */ plugin->config_size = sizeof(hdlc_config_t); @@ -127,22 +135,27 @@ dlt_hdlc_cleanup(tcpeditdlt_t *ctx) tcpeditdlt_plugin_t *plugin; assert(ctx); - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) { - tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name); + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); return TCPEDIT_ERROR; } + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + safe_free(plugin->config); + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } + if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); ctx->decoded_extra = NULL; ctx->decoded_extra_size = 0; } - - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } return TCPEDIT_OK; /* success */ } diff --git a/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c b/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c index f2c8c5c85..1c25ba4a4 100644 --- a/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c +++ b/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c @@ -109,8 +109,16 @@ dlt_ieee80211_init(tcpeditdlt_t *ctx) } /* allocate memory for our decode extra data */ - ctx->decoded_extra_size = sizeof(ieee80211_extra_t); - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < sizeof(ieee80211_extra_t)) { + ctx->decoded_extra_size = sizeof(ieee80211_extra_t); + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = sizeof(ieee80211_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } /* allocate memory for our config data */ plugin->config_size = sizeof(ieee80211_config_t); @@ -132,22 +140,27 @@ dlt_ieee80211_cleanup(tcpeditdlt_t *ctx) tcpeditdlt_plugin_t *plugin; assert(ctx); - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) { - tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name); + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); return TCPEDIT_ERROR; } + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + safe_free(plugin->config); + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } + if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); ctx->decoded_extra = NULL; ctx->decoded_extra_size = 0; } - - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } return TCPEDIT_OK; /* success */ } diff --git a/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c b/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c index 2a9b0ef1f..ceef24536 100644 --- a/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c +++ b/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c @@ -104,8 +104,16 @@ dlt_linuxsll_init(tcpeditdlt_t *ctx) } /* allocate memory for our decode extra data */ - ctx->decoded_extra_size = sizeof(linuxsll_extra_t); - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < sizeof(linuxsll_extra_t)) { + ctx->decoded_extra_size = sizeof(linuxsll_extra_t); + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = sizeof(linuxsll_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } /* allocate memory for our config data */ plugin->config_size = sizeof(linuxsll_config_t); @@ -125,11 +133,22 @@ dlt_linuxsll_cleanup(tcpeditdlt_t *ctx) tcpeditdlt_plugin_t *plugin; assert(ctx); - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) { - tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name); + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); return TCPEDIT_ERROR; } + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + safe_free(plugin->config); + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } + /* FIXME: make this function do something if necessary */ if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); @@ -137,12 +156,6 @@ dlt_linuxsll_cleanup(tcpeditdlt_t *ctx) ctx->decoded_extra_size = 0; } - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } - return TCPEDIT_OK; /* success */ } diff --git a/src/tcpedit/plugins/dlt_plugins.c b/src/tcpedit/plugins/dlt_plugins.c index 4577f90e1..a0a5166d7 100644 --- a/src/tcpedit/plugins/dlt_plugins.c +++ b/src/tcpedit/plugins/dlt_plugins.c @@ -452,6 +452,8 @@ tcpedit_dlt_dst(tcpeditdlt_t *ctx) void tcpedit_dlt_cleanup(tcpeditdlt_t *ctx) { + tcpeditdlt_plugin_t *plugin; + assert(ctx); if (ctx->encoder != NULL) @@ -460,12 +462,26 @@ tcpedit_dlt_cleanup(tcpeditdlt_t *ctx) if (ctx->decoder != NULL) ctx->decoder->plugin_cleanup(ctx); + if (ctx->plugins != NULL) + ctx->plugins->plugin_cleanup(ctx); + + plugin = ctx->plugins; + while (plugin != NULL) { + tcpeditdlt_plugin_t *plugin_next = plugin->next; + safe_free(plugin); + plugin = plugin_next; + } + #ifdef FORCE_ALIGN safe_free(ctx->l3buff); #endif - if (ctx->decoded_extra != NULL) + if (ctx->decoded_extra != NULL) { + printf("dlt_plugins.c: free ctx->decoded_extra=%p\n", ctx->decoded_extra); safe_free(ctx->decoded_extra); + ctx->decoded_extra = NULL; + ctx->decoded_extra_size = 0; + } safe_free(ctx); } diff --git a/src/tcpedit/plugins/dlt_radiotap/radiotap.c b/src/tcpedit/plugins/dlt_radiotap/radiotap.c index c7e843bea..8e2b72873 100644 --- a/src/tcpedit/plugins/dlt_radiotap/radiotap.c +++ b/src/tcpedit/plugins/dlt_radiotap/radiotap.c @@ -110,8 +110,16 @@ dlt_radiotap_init(tcpeditdlt_t *ctx) } /* allocate memory for our decode extra data */ - ctx->decoded_extra_size = sizeof(radiotap_extra_t); - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < sizeof(radiotap_extra_t)) { + ctx->decoded_extra_size = sizeof(radiotap_extra_t); + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = sizeof(radiotap_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } /* allocate memory for our config data */ plugin->config_size = sizeof(radiotap_config_t); @@ -131,23 +139,28 @@ dlt_radiotap_cleanup(tcpeditdlt_t *ctx) tcpeditdlt_plugin_t *plugin; assert(ctx); - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) { - tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name); + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); return TCPEDIT_ERROR; } + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + safe_free(plugin->config); + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } + if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); ctx->decoded_extra = NULL; ctx->decoded_extra_size = 0; } - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } - return TCPEDIT_OK; /* success */ } diff --git a/src/tcpedit/plugins/dlt_raw/raw.c b/src/tcpedit/plugins/dlt_raw/raw.c index 076e2f4ca..027d5ab84 100644 --- a/src/tcpedit/plugins/dlt_raw/raw.c +++ b/src/tcpedit/plugins/dlt_raw/raw.c @@ -104,8 +104,16 @@ dlt_raw_init(tcpeditdlt_t *ctx) } /* allocate memory for our config data */ - ctx->decoded_extra_size = sizeof(raw_extra_t); - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < sizeof(raw_extra_t)) { + ctx->decoded_extra_size = sizeof(raw_extra_t); + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = sizeof(raw_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } /* allocate memory for our config data */ plugin->config_size = sizeof(raw_config_t); @@ -125,23 +133,27 @@ dlt_raw_cleanup(tcpeditdlt_t *ctx) tcpeditdlt_plugin_t *plugin; assert(ctx); - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) { - tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name); + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); return TCPEDIT_ERROR; } - /* FIXME: make this function do something if necessary */ + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + safe_free(plugin->config); + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } + if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); ctx->decoded_extra = NULL; ctx->decoded_extra_size = 0; } - - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } return TCPEDIT_OK; /* success */ } diff --git a/src/tcpedit/plugins/dlt_user/user.c b/src/tcpedit/plugins/dlt_user/user.c index 5e713b6cb..e2545ef23 100644 --- a/src/tcpedit/plugins/dlt_user/user.c +++ b/src/tcpedit/plugins/dlt_user/user.c @@ -104,8 +104,16 @@ dlt_user_init(tcpeditdlt_t *ctx) /* allocate memory for our decode extra data - plus some space for * other DLT decodes */ - ctx->decoded_extra_size = USER_L2MAXLEN; - ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + if (ctx->decoded_extra_size > 0) { + if (ctx->decoded_extra_size < USER_L2MAXLEN) { + ctx->decoded_extra_size = USER_L2MAXLEN; + ctx->decoded_extra = safe_realloc(ctx->decoded_extra, + ctx->decoded_extra_size); + } + } else { + ctx->decoded_extra_size = USER_L2MAXLEN; + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); + } /* allocate memory for our config data */ plugin->config_size = sizeof(user_config_t); @@ -129,23 +137,28 @@ dlt_user_cleanup(tcpeditdlt_t *ctx) tcpeditdlt_plugin_t *plugin; assert(ctx); - if ((plugin = tcpedit_dlt_getplugin(ctx, dlt_value)) == NULL) { - tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", dlt_name); + plugin = ctx->plugins; + if (plugin == NULL) { + tcpedit_seterr(ctx->tcpedit, "Unable to cleanup unregistered plugin %s", + dlt_name); return TCPEDIT_ERROR; } + while (plugin != NULL) { + safe_free(plugin->name); + plugin->name = NULL; + safe_free(plugin->config); + plugin->config = NULL; + plugin->config_size = 0; + plugin = plugin->next; + } + /* FIXME: make this function do something if necessary */ if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); ctx->decoded_extra = NULL; ctx->decoded_extra_size = 0; } - - if (plugin->config != NULL) { - safe_free(plugin->config); - plugin->config = NULL; - plugin->config_size = 0; - } return TCPEDIT_OK; /* success */ } diff --git a/src/tcpedit/portmap.c b/src/tcpedit/portmap.c index 82090799f..c5d59cc9d 100644 --- a/src/tcpedit/portmap.c +++ b/src/tcpedit/portmap.c @@ -125,8 +125,8 @@ ports2PORT(char *ports) portmap->from = htons(i); portmap->to = htons(to_l); portmap->next = new_portmap(); - portmap_last = portmap; portmap = portmap->next; + portmap_last = portmap; } portmap_last->next = NULL; } @@ -135,7 +135,7 @@ ports2PORT(char *ports) from_begin = strtok_r(from_s, "+", &token2); from_l = strtol(from_begin, &badchar, 10); if (strlen(badchar) != 0) { - free(portmap); + safe_free(portmap); return NULL; } portmap->to = htons(to_l); @@ -147,7 +147,7 @@ ports2PORT(char *ports) portmap = portmap_head; while (portmap) { tcpedit_portmap_t *tmp_portmap = portmap->next; - free(portmap); + safe_free(portmap); portmap = tmp_portmap; } return NULL; @@ -166,7 +166,7 @@ ports2PORT(char *ports) */ from_l = strtol(from_s, &badchar, 10); if (strlen(badchar) != 0 || from_l > 65535 || from_l < 0) { - free(portmap); + safe_free(portmap); return NULL; } portmap->to = htons(to_l); diff --git a/src/tcpedit/tcpedit.c b/src/tcpedit/tcpedit.c index 86360f798..3b6a409e7 100644 --- a/src/tcpedit/tcpedit.c +++ b/src/tcpedit/tcpedit.c @@ -561,22 +561,78 @@ tcpedit_checkerror(tcpedit_t *tcpedit, const int rcode, const char *prefix) { /** * \brief Cleans up after ourselves. Return 0 on success. * - * Clean up after ourselves, but does not actually free the ptr. + * Clean up after ourselves and free the ptr. */ int -tcpedit_close(tcpedit_t *tcpedit) +tcpedit_close(tcpedit_t **tcpedit_ex) { - assert(tcpedit); + assert(*tcpedit_ex); + tcpedit_t *tcpedit; + + tcpedit = *tcpedit_ex; + dbgx(1, "tcpedit processed " COUNTER_SPEC " bytes in " COUNTER_SPEC " packets.", tcpedit->runtime.total_bytes, tcpedit->runtime.pkts_edited); - /* free buffer if required */ + /* free if required */ + if (tcpedit->dlt_ctx) { + tcpedit_dlt_cleanup(tcpedit->dlt_ctx); + tcpedit->dlt_ctx = NULL; + } + + if (tcpedit->cidrmap1) { + destroy_cidr(tcpedit->cidrmap1->from); + tcpedit->cidrmap1->from = NULL; + destroy_cidr(tcpedit->cidrmap1->to); + tcpedit->cidrmap1->to = NULL; + } + + if (tcpedit->cidrmap2 && tcpedit->cidrmap2 != tcpedit->cidrmap1) { + destroy_cidr(tcpedit->cidrmap2->from); + tcpedit->cidrmap2->from = NULL; + destroy_cidr(tcpedit->cidrmap2->to); + tcpedit->cidrmap2->to = NULL; + safe_free(tcpedit->cidrmap2); + tcpedit->cidrmap2 = NULL; + } + + safe_free(tcpedit->cidrmap1); + tcpedit->cidrmap1 = NULL; + + if (tcpedit->srcipmap) { + destroy_cidr(tcpedit->srcipmap->from); + tcpedit->srcipmap->from = NULL; + destroy_cidr(tcpedit->srcipmap->to); + tcpedit->srcipmap->to = NULL; + } + + if (tcpedit->dstipmap && tcpedit->dstipmap != tcpedit->srcipmap) { + destroy_cidr(tcpedit->dstipmap->from); + tcpedit->dstipmap->from = NULL; + destroy_cidr(tcpedit->dstipmap->to); + tcpedit->dstipmap->to = NULL; + safe_free(tcpedit->dstipmap); + tcpedit->dstipmap = NULL; + } + + safe_free(tcpedit->srcipmap); + tcpedit->srcipmap = NULL; + + if (tcpedit->portmap) { + free_portmap(tcpedit->portmap); + tcpedit->portmap = NULL; + } + #ifdef FORCE_ALIGN safe_free(tcpedit->runtime.l3buff); + tcpedit->runtime.l3buff = NULL; #endif + safe_free(*tcpedit_ex); + *tcpedit_ex = NULL; + return 0; } diff --git a/src/tcpedit/tcpedit.h b/src/tcpedit/tcpedit.h index 7030833f3..7be48de66 100644 --- a/src/tcpedit/tcpedit.h +++ b/src/tcpedit/tcpedit.h @@ -48,7 +48,7 @@ int tcpedit_validate(tcpedit_t *tcpedit); int tcpedit_packet(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr, u_char **pktdata, tcpr_dir_t direction); -int tcpedit_close(tcpedit_t *tcpedit); +int tcpedit_close(tcpedit_t **tcpedit_ex); int tcpedit_get_output_dlt(tcpedit_t *tcpedit); const u_char *tcpedit_l3data(tcpedit_t *tcpedit, tcpedit_coder code, u_char *packet, const int pktlen); diff --git a/src/tcpedit/tcpedit_types.h b/src/tcpedit/tcpedit_types.h index 049b1228e..d3210458b 100644 --- a/src/tcpedit/tcpedit_types.h +++ b/src/tcpedit/tcpedit_types.h @@ -105,7 +105,6 @@ typedef struct tcpedit_portmap_s { typedef struct { bool validated; /* have we run tcpedit_validate()? */ struct tcpeditdlt_s *dlt_ctx; - tcpedit_packet_t *packet; /* runtime variables, don't mess with these */ tcpedit_runtime_t runtime; diff --git a/src/tcpreplay.c b/src/tcpreplay.c index 2241113a8..834a8e060 100644 --- a/src/tcpreplay.c +++ b/src/tcpreplay.c @@ -91,12 +91,14 @@ main(int argc, char *argv[]) /* parse the tcpedit args */ rcode = tcpedit_post_args(tcpedit); if (rcode < 0) { + tcpedit_close(&tcpedit); errx(-1, "Unable to parse args: %s", tcpedit_geterr(tcpedit)); } else if (rcode == 1) { warnx("%s", tcpedit_geterr(tcpedit)); } if (tcpedit_validate(tcpedit) < 0) { + tcpedit_close(&tcpedit); errx(-1, "Unable to edit packets given options:\n%s", tcpedit_geterr(tcpedit)); } @@ -140,6 +142,9 @@ main(int argc, char *argv[]) if (rcode < 0) { notice("\nFailed: %s\n", tcpreplay_geterr(ctx)); +#ifdef TCPREPLAY_EDIT + tcpedit_close(&tcpedit); +#endif exit(rcode); } else if (rcode == 1) { notice("\nWarning: %s\n", tcpreplay_getwarn(ctx)); @@ -162,6 +167,9 @@ main(int argc, char *argv[]) #ifdef TIMESTAMP_TRACE dump_timestamp_trace_array(&ctx->stats.start_time, &ctx->stats.end_time, ctx->options->speed.speed); +#endif +#ifdef TCPREPLAY_EDIT + tcpedit_close(&tcpedit); #endif tcpreplay_close(ctx); restore_stdin(); diff --git a/src/tcprewrite.c b/src/tcprewrite.c index 535961f5f..57c7c9bb3 100644 --- a/src/tcprewrite.c +++ b/src/tcprewrite.c @@ -86,12 +86,14 @@ main(int argc, char *argv[]) /* parse the tcpedit args */ rcode = tcpedit_post_args(tcpedit); if (rcode < 0) { + tcpedit_close(&tcpedit); errx(-1, "Unable to parse args: %s", tcpedit_geterr(tcpedit)); } else if (rcode == 1) { warnx("%s", tcpedit_geterr(tcpedit)); } if (tcpedit_validate(tcpedit) < 0) { + tcpedit_close(&tcpedit); errx(-1, "Unable to edit packets given options:\n%s", tcpedit_geterr(tcpedit)); } @@ -103,16 +105,20 @@ main(int argc, char *argv[]) options.outfile = safe_strdup(OPT_ARG(OUTFILE)); dbgx(1, "Rewriting DLT to %s", pcap_datalink_val_to_name(tcpedit_get_output_dlt(tcpedit))); - if ((dlt_pcap = pcap_open_dead(tcpedit_get_output_dlt(tcpedit), 65535)) == NULL) + if ((dlt_pcap = pcap_open_dead(tcpedit_get_output_dlt(tcpedit), 65535)) == NULL) { + tcpedit_close(&tcpedit); err(-1, "Unable to open dead pcap handle."); + } dbgx(1, "DLT of dlt_pcap is %s", pcap_datalink_val_to_name(pcap_datalink(dlt_pcap))); #ifdef ENABLE_FRAGROUTE if (options.fragroute_args) { - if ((options.frag_ctx = fragroute_init(65535, pcap_datalink(dlt_pcap), options.fragroute_args, ebuf)) == NULL) + if ((options.frag_ctx = fragroute_init(65535, pcap_datalink(dlt_pcap), options.fragroute_args, ebuf)) == NULL) { + tcpedit_close(&tcpedit); errx(-1, "%s", ebuf); + } } #endif @@ -122,18 +128,23 @@ main(int argc, char *argv[]) } #endif - if ((options.pout = pcap_dump_open(dlt_pcap, options.outfile)) == NULL) + if ((options.pout = pcap_dump_open(dlt_pcap, options.outfile)) == NULL) { + tcpedit_close(&tcpedit); errx(-1, "Unable to open output pcap file: %s", pcap_geterr(dlt_pcap)); + } + pcap_close(dlt_pcap); /* rewrite packets */ - if (rewrite_packets(tcpedit, options.pin, options.pout) != 0) + if (rewrite_packets(tcpedit, options.pin, options.pout) != 0) { + tcpedit_close(&tcpedit); errx(-1, "Error rewriting packets: %s", tcpedit_geterr(tcpedit)); - + } /* clean up after ourselves */ pcap_dump_close(options.pout); pcap_close(options.pin); + tcpedit_close(&tcpedit); #ifdef ENABLE_VERBOSE tcpdump_close(&tcpdump);