diff --git a/docs/CHANGELOG b/docs/CHANGELOG index 4294c9082..c0fe73ba4 100644 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -11,6 +11,7 @@ - Rewrite zero IP total length field to match the actual packet length (#406) - stack-buffer-overflow in tcpcapinfo (#405) - tcpprep --include option does not exclude (#404) + - Negative-size-param memset in dlt_radiotap_get_80211 (#402) 05/10/2017 Version 4.2.6 - Test fails on sparc64 (#393) diff --git a/src/tcpedit/plugins/dlt_en10mb/en10mb.c b/src/tcpedit/plugins/dlt_en10mb/en10mb.c index a8ba2be52..8e08c9464 100644 --- a/src/tcpedit/plugins/dlt_en10mb/en10mb.c +++ b/src/tcpedit/plugins/dlt_en10mb/en10mb.c @@ -104,8 +104,10 @@ dlt_en10mb_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - ctx->decoded_extra = safe_malloc(sizeof(en10mb_extra_t)); - plugin->config = safe_malloc(sizeof(en10mb_config_t)); + 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; /* init vlan user values to -1 to indicate not set */ @@ -135,11 +137,13 @@ dlt_en10mb_cleanup(tcpeditdlt_t *ctx) 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 */ @@ -222,7 +226,12 @@ dlt_en10mb_parse_opts(tcpeditdlt_t *ctx) assert(ctx); plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = (en10mb_config_t *)plugin->config; + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; /* --subsmacs */ if (HAVE_OPT(ENET_SUBSMAC)) { @@ -381,6 +390,9 @@ dlt_en10mb_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen) memcpy(&(ctx->srcaddr.ethernet), &(eth->ether_shost), ETHER_ADDR_LEN); extra = (en10mb_extra_t *)ctx->decoded_extra; + if (ctx->decoded_extra_size < sizeof(*extra)) + return TCPEDIT_ERROR; + extra->vlan = 0; /* get the L3 protocol type & L2 len*/ @@ -436,9 +448,17 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir) } plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = plugin->config; + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; + extra = (en10mb_extra_t *)ctx->decoded_extra; - + if (ctx->decoded_extra_size < sizeof(*extra)) + return TCPEDIT_ERROR; + /* figure out the new layer2 length, first for the case: ethernet -> ethernet? */ if (ctx->decoder->dlt == dlt_value) { if ((ctx->l2len == TCPR_802_1Q_H && config->vlan == TCPEDIT_VLAN_OFF) || diff --git a/src/tcpedit/plugins/dlt_hdlc/hdlc.c b/src/tcpedit/plugins/dlt_hdlc/hdlc.c index fa919755e..90942d25d 100644 --- a/src/tcpedit/plugins/dlt_hdlc/hdlc.c +++ b/src/tcpedit/plugins/dlt_hdlc/hdlc.c @@ -102,13 +102,12 @@ dlt_hdlc_init(tcpeditdlt_t *ctx) } /* allocate memory for our deocde extra data */ - if (sizeof(hdlc_extra_t) > 0) - ctx->decoded_extra = safe_malloc(sizeof(hdlc_extra_t)); + ctx->decoded_extra_size = sizeof(hdlc_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); /* allocate memory for our config data */ - if (sizeof(hdlc_config_t) > 0) - plugin->config = safe_malloc(sizeof(hdlc_config_t)); - + plugin->config_size = sizeof(hdlc_config_t); + plugin->config = safe_malloc(plugin->config_size); config = (hdlc_config_t *)plugin->config; /* default to unset */ @@ -136,11 +135,13 @@ dlt_hdlc_cleanup(tcpeditdlt_t *ctx) 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 */ @@ -159,9 +160,15 @@ dlt_hdlc_parse_opts(tcpeditdlt_t *ctx) hdlc_config_t *config; assert(ctx); + plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = plugin->config; - + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; + if (HAVE_OPT(HDLC_CONTROL)) { config->control = (uint16_t)OPT_VALUE_HDLC_CONTROL; } @@ -191,10 +198,14 @@ dlt_hdlc_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen) assert(ctx); assert(packet); - if (pktlen < 4) + if (pktlen < sizeof(*hdlc)) return TCPEDIT_ERROR; + if (ctx->decoded_extra_size < sizeof(*extra)) + return TCPEDIT_ERROR; + extra = (hdlc_extra_t *)ctx->decoded_extra; + hdlc = (cisco_hdlc_t *)packet; ctx->proto = hdlc->protocol; @@ -223,7 +234,10 @@ dlt_hdlc_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t di assert(ctx); assert(packet); - if (pktlen < 4) + if (pktlen < sizeof(*hdlc)) + return TCPEDIT_ERROR; + + if (ctx->decoded_extra_size < sizeof(*extra)) return TCPEDIT_ERROR; /* Make room for our new l2 header if old l2len != 4 */ @@ -243,8 +257,16 @@ dlt_hdlc_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t di */ hdlc = (cisco_hdlc_t *)packet; plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = plugin->config; + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; + extra = (hdlc_extra_t *)ctx->decoded_extra; + if (ctx->decoded_extra_size < sizeof(*extra)) + return TCPEDIT_ERROR; /* set the address field */ if (config->address < 65535) { diff --git a/src/tcpedit/plugins/dlt_hdlc/hdlc_types.h b/src/tcpedit/plugins/dlt_hdlc/hdlc_types.h index 5fe7d14fb..4c9c1cd0f 100644 --- a/src/tcpedit/plugins/dlt_hdlc/hdlc_types.h +++ b/src/tcpedit/plugins/dlt_hdlc/hdlc_types.h @@ -33,9 +33,14 @@ extern "C" { * Example: Ethernet VLAN tag info */ typedef struct { - int hdlc; /* set to 1 if values below are filled out */ - u_int8_t address; - u_int8_t control; + union { + struct { + int hdlc; /* set to 1 if values below are filled out */ + u_int8_t address; + u_int8_t control; + }; + u_char packet[MAXPACKET]; + }; } hdlc_extra_t; diff --git a/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c b/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c index 945a81a89..cd6ee5d3b 100644 --- a/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c +++ b/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c @@ -108,13 +108,13 @@ dlt_ieee80211_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - /* allocate memory for our deocde extra data */ - if (sizeof(ieee80211_extra_t) > 0) - ctx->decoded_extra = safe_malloc(sizeof(ieee80211_extra_t)); + /* allocate memory for our decode extra data */ + ctx->decoded_extra_size = sizeof(ieee80211_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); /* allocate memory for our config data */ - if (sizeof(ieee80211_config_t) > 0) - plugin->config = safe_malloc(sizeof(ieee80211_config_t)); + plugin->config_size = sizeof(ieee80211_config_t); + plugin->config = safe_malloc(plugin->config_size); /* FIXME: set default config values here */ @@ -140,11 +140,13 @@ dlt_ieee80211_cleanup(tcpeditdlt_t *ctx) 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_types.h b/src/tcpedit/plugins/dlt_ieee80211/ieee80211_types.h index 5f31cee97..b59d3bf27 100644 --- a/src/tcpedit/plugins/dlt_ieee80211/ieee80211_types.h +++ b/src/tcpedit/plugins/dlt_ieee80211/ieee80211_types.h @@ -83,8 +83,7 @@ typedef struct { * Example: Ethernet VLAN tag info */ typedef struct { - /* dummy entry for SunPro compiler which doesn't like empty structs */ - int dummy; + u_char packet[MAXPACKET]; } ieee80211_extra_t; /* diff --git a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c index 258ac8ac1..ff1708051 100644 --- a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c +++ b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c @@ -117,8 +117,8 @@ dlt_jnpr_ether_init(tcpeditdlt_t *ctx) } /* allocate memory for our config data */ - if (sizeof(jnpr_ether_config_t) > 0) - plugin->config = safe_malloc(sizeof(jnpr_ether_config_t)); + plugin->config_size = sizeof(jnpr_ether_config_t); + plugin->config = safe_malloc(plugin->config_size); return TCPEDIT_OK; /* success */ } @@ -164,6 +164,7 @@ dlt_jnpr_ether_cleanup(tcpeditdlt_t *ctx) if (ctx->decoded_extra != NULL) { safe_free(ctx->decoded_extra); ctx->decoded_extra = NULL; + ctx->decoded_extra_size = 0; } if (plugin->config != NULL) { @@ -171,6 +172,7 @@ dlt_jnpr_ether_cleanup(tcpeditdlt_t *ctx) config = (jnpr_ether_config_t *)ctx->encoder->config; tcpedit_dlt_cleanup(config->subctx); 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 6f50fdb5d..98a9e1597 100644 --- a/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c +++ b/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c @@ -103,14 +103,13 @@ dlt_linuxsll_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - /* allocate memory for our deocde extra data */ - if (sizeof(linuxsll_extra_t) > 0) - ctx->decoded_extra = safe_malloc(sizeof(linuxsll_extra_t)); + /* allocate memory for our decode extra data */ + ctx->decoded_extra_size = sizeof(linuxsll_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); /* allocate memory for our config data */ - if (sizeof(linuxsll_config_t) > 0) - plugin->config = safe_malloc(sizeof(linuxsll_config_t)); - + plugin->config_size = sizeof(linuxsll_config_t); + plugin->config = safe_malloc(plugin->config_size); return TCPEDIT_OK; /* success */ } @@ -135,11 +134,13 @@ dlt_linuxsll_cleanup(tcpeditdlt_t *ctx) 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_types.h b/src/tcpedit/plugins/dlt_linuxsll/linuxsll_types.h index 7ba5e50d4..00626db3f 100644 --- a/src/tcpedit/plugins/dlt_linuxsll/linuxsll_types.h +++ b/src/tcpedit/plugins/dlt_linuxsll/linuxsll_types.h @@ -32,8 +32,7 @@ extern "C" { * Example: Ethernet VLAN tag info */ typedef struct { - /* dummy entry for SunPro compiler which doesn't like empty structs */ - int dummy; + u_char packet[MAXPACKET]; } linuxsll_extra_t; diff --git a/src/tcpedit/plugins/dlt_null/null.c b/src/tcpedit/plugins/dlt_null/null.c index 8477580ea..bf78544a2 100644 --- a/src/tcpedit/plugins/dlt_null/null.c +++ b/src/tcpedit/plugins/dlt_null/null.c @@ -140,11 +140,13 @@ dlt_null_cleanup(tcpeditdlt_t *ctx) 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_plugins.c b/src/tcpedit/plugins/dlt_plugins.c index 61e5a1f74..1b1f78b23 100644 --- a/src/tcpedit/plugins/dlt_plugins.c +++ b/src/tcpedit/plugins/dlt_plugins.c @@ -443,7 +443,7 @@ tcpedit_dlt_cleanup(tcpeditdlt_t *ctx) if (ctx->decoded_extra != NULL) safe_free(ctx->decoded_extra); - + safe_free(ctx); } diff --git a/src/tcpedit/plugins/dlt_pppserial/pppserial.c b/src/tcpedit/plugins/dlt_pppserial/pppserial.c index a037994ad..a140da3fe 100644 --- a/src/tcpedit/plugins/dlt_pppserial/pppserial.c +++ b/src/tcpedit/plugins/dlt_pppserial/pppserial.c @@ -162,11 +162,13 @@ dlt_pppserial_cleanup(tcpeditdlt_t *ctx) 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_radiotap/radiotap.c b/src/tcpedit/plugins/dlt_radiotap/radiotap.c index e89a4b86a..7d6443aad 100644 --- a/src/tcpedit/plugins/dlt_radiotap/radiotap.c +++ b/src/tcpedit/plugins/dlt_radiotap/radiotap.c @@ -109,13 +109,13 @@ dlt_radiotap_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - /* allocate memory for our deocde extra data */ - if (sizeof(radiotap_extra_t) > 0) - ctx->decoded_extra = safe_malloc(sizeof(radiotap_extra_t)); + /* allocate memory for our decode extra data */ + ctx->decoded_extra_size = sizeof(radiotap_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); /* allocate memory for our config data */ - if (sizeof(radiotap_config_t) > 0) - plugin->config = safe_malloc(sizeof(radiotap_config_t)); + plugin->config_size = sizeof(radiotap_config_t); + plugin->config = safe_malloc(plugin->config_size); return TCPEDIT_OK; /* success */ } @@ -139,11 +139,13 @@ dlt_radiotap_cleanup(tcpeditdlt_t *ctx) 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 */ @@ -188,13 +190,15 @@ dlt_radiotap_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen) radiolen = dlt_radiotap_l2len(ctx, packet, pktlen); data = dlt_radiotap_get_80211(ctx, packet, pktlen, radiolen); - + if (!data) + return TCPEDIT_ERROR; + /* ieee80211 decoder fills out everything */ rcode = dlt_ieee80211_decode(ctx, data, pktlen - radiolen); /* need to override the ieee802.11 l2 length result */ ctx->l2len = dlt_radiotap_80211_l2len(ctx, packet, pktlen); - return rcode; + return (ctx->l2len > 0) ? rcode : TCPEDIT_ERROR; } /* @@ -228,6 +232,9 @@ dlt_radiotap_proto(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen) return TCPEDIT_ERROR; radiolen = dlt_radiotap_l2len(ctx, packet, pktlen); + if (radiolen < 0 || radiolen > pktlen) + return TCPEDIT_ERROR; + data = dlt_radiotap_get_80211(ctx, packet, pktlen, radiolen); return dlt_ieee80211_proto(ctx, data, pktlen - radiolen); } @@ -348,8 +355,12 @@ dlt_radiotap_get_80211(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen radiotap_extra_t *extra; static COUNTER lastpacket = 0; + if (ctx->decoded_extra_size < sizeof(*extra)) + return NULL; + extra = (radiotap_extra_t *)(ctx->decoded_extra); - if (lastpacket != ctx->tcpedit->runtime.packetnum) { + if (pktlen >= radiolen && (pktlen - radiolen) >= sizeof(extra->packet) && + lastpacket != ctx->tcpedit->runtime.packetnum) { memcpy(extra->packet, &packet[radiolen], pktlen - radiolen); lastpacket = ctx->tcpedit->runtime.packetnum; } diff --git a/src/tcpedit/plugins/dlt_raw/raw.c b/src/tcpedit/plugins/dlt_raw/raw.c index 4db3a5460..3d6fcb762 100644 --- a/src/tcpedit/plugins/dlt_raw/raw.c +++ b/src/tcpedit/plugins/dlt_raw/raw.c @@ -103,13 +103,13 @@ dlt_raw_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - /* allocate memory for our deocde extra data */ - if (sizeof(raw_extra_t) > 0) - ctx->decoded_extra = safe_malloc(sizeof(raw_extra_t)); + /* allocate memory for our config data */ + ctx->decoded_extra_size = sizeof(raw_extra_t); + ctx->decoded_extra = safe_malloc(ctx->decoded_extra_size); /* allocate memory for our config data */ - if (sizeof(raw_config_t) > 0) - plugin->config = safe_malloc(sizeof(raw_config_t)); + plugin->config_size = sizeof(raw_config_t); + plugin->config = safe_malloc(plugin->config_size); return TCPEDIT_OK; /* success */ } @@ -134,11 +134,13 @@ dlt_raw_cleanup(tcpeditdlt_t *ctx) 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.h b/src/tcpedit/plugins/dlt_raw/raw.h index e687624db..6b91392db 100644 --- a/src/tcpedit/plugins/dlt_raw/raw.h +++ b/src/tcpedit/plugins/dlt_raw/raw.h @@ -41,12 +41,10 @@ u_char *dlt_raw_get_mac(tcpeditdlt_t *ctx, tcpeditdlt_mac_type_t mac, const u_ch * Example: Ethernet VLAN tag info */ struct raw_extra_s { - /* dummy entry for SunPro compiler which doesn't like empty structs */ - int dummy; + u_char packet[MAXPACKET]; }; typedef struct raw_extra_s raw_extra_t; - /* * FIXME: structure to hold any data in the tcpeditdlt_plugin_t->config * Things like: diff --git a/src/tcpedit/plugins/dlt_raw/raw_opts.def b/src/tcpedit/plugins/dlt_raw/raw_opts.def index 987f459dd..a70b3803d 100644 --- a/src/tcpedit/plugins/dlt_raw/raw_opts.def +++ b/src/tcpedit/plugins/dlt_raw/raw_opts.def @@ -1 +1 @@ -/* No options for DLT_RAW as it's an decoder only plugin */ +/* No options for DLT_RAW as it's a decoder only plugin */ diff --git a/src/tcpedit/plugins/dlt_user/user.c b/src/tcpedit/plugins/dlt_user/user.c index 4c2566fcd..061f733df 100644 --- a/src/tcpedit/plugins/dlt_user/user.c +++ b/src/tcpedit/plugins/dlt_user/user.c @@ -101,13 +101,15 @@ dlt_user_init(tcpeditdlt_t *ctx) return TCPEDIT_ERROR; } - /* allocate memory for our deocde extra data */ - if (sizeof(user_extra_t) > 0) - ctx->decoded_extra = safe_malloc(sizeof(user_extra_t)); + /* 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); /* allocate memory for our config data */ - if (sizeof(user_config_t) > 0) - plugin->config = safe_malloc(sizeof(user_config_t)); + plugin->config_size = sizeof(user_config_t); + plugin->config = safe_malloc(plugin->config_size); config = (user_config_t *)plugin->config; config->length = -1; @@ -136,11 +138,13 @@ dlt_user_cleanup(tcpeditdlt_t *ctx) 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 */ @@ -160,7 +164,12 @@ dlt_user_parse_opts(tcpeditdlt_t *ctx) assert(ctx); plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = plugin->config; + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; /* * --user-dlt will override the output DLT type, otherwise we'll use @@ -227,7 +236,12 @@ dlt_user_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir) return TCPEDIT_ERROR; plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = plugin->config; + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; /* Make room for our new l2 header if l2len != config->length */ if (ctx->l2len > config->length) { @@ -280,7 +294,7 @@ dlt_user_get_layer3(tcpeditdlt_t *ctx, u_char *packet, const int pktlen) /* FIXME: Is there anything else we need to do?? */ l2len = dlt_user_l2len(ctx, packet, pktlen); - if (pktlen < l2len) + if (l2len < 0 || pktlen < l2len) return NULL; return tcpedit_dlt_l3data_copy(ctx, packet, pktlen, l2len); @@ -321,7 +335,12 @@ dlt_user_l2len(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen) assert(packet); plugin = tcpedit_dlt_getplugin(ctx, dlt_value); + if (!plugin) + return TCPEDIT_ERROR; + config = plugin->config; + if (plugin->config_size < sizeof(*config)) + return TCPEDIT_ERROR; return config->length; } diff --git a/src/tcpedit/plugins/dlt_utils.c b/src/tcpedit/plugins/dlt_utils.c index 3c5f35980..043260f4d 100644 --- a/src/tcpedit/plugins/dlt_utils.c +++ b/src/tcpedit/plugins/dlt_utils.c @@ -268,6 +268,7 @@ tcpedit_dlt_copy_decoder_state(tcpeditdlt_t *ctx, tcpeditdlt_t *subctx) /* just need to copy the ptr */ ctx->decoded_extra = subctx->decoded_extra; + ctx->decoded_extra_size = subctx->decoded_extra_size; /* * the first decoder should of alraedy specified it's l2len, so we need to diff --git a/src/tcpedit/plugins_types.h b/src/tcpedit/plugins_types.h index 4008c4c94..7e64d056c 100644 --- a/src/tcpedit/plugins_types.h +++ b/src/tcpedit/plugins_types.h @@ -92,6 +92,7 @@ struct tcpeditdlt_plugin_s { tcpeditdlt_l2addr_type_t (*plugin_l2addr_type)(void); u_char *(*plugin_get_mac)(tcpeditdlt_t *, tcpeditdlt_mac_type_t, const u_char *, const int); void *config; /* user configuration data for the encoder */ + size_t config_size; }; @@ -126,6 +127,7 @@ struct tcpeditdlt_s { int l2len; /* set by decoder and updated by encoder */ u_int16_t proto; /* layer 3 proto type?? */ void *decoded_extra; /* any extra L2 data from decoder like VLAN tags */ + size_t decoded_extra_size; /* size of decode_extra buffer */ u_char srcmac[MAX_MAC_LEN]; /* buffers to store the src & dst MAC */ u_char dstmac[MAX_MAC_LEN]; };