Skip to content

Commit

Permalink
#402 fix potential overruns in all DLT plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
fklassen committed Jan 22, 2018
1 parent fcd470f commit 746b10a
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 39 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 23 additions & 3 deletions src/tcpedit/plugins/dlt_en10mb/en10mb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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*/
Expand Down Expand Up @@ -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) ||
Expand Down
38 changes: 30 additions & 8 deletions src/tcpedit/plugins/dlt_hdlc/hdlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand All @@ -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) {
Expand Down
10 changes: 6 additions & 4 deletions src/tcpedit/plugins/dlt_ieee80211/ieee80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ dlt_ieee80211_init(tcpeditdlt_t *ctx)
}

/* allocate memory for our deocde extra data */
if (sizeof(ieee80211_extra_t) > 0)
ctx->decoded_extra = safe_malloc(sizeof(ieee80211_extra_t));
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 */

Expand All @@ -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 */
Expand Down
6 changes: 4 additions & 2 deletions src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
}
Expand Down Expand Up @@ -164,13 +164,15 @@ 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) {
/* clean up the en10mb plugin */
config = (jnpr_ether_config_t *)ctx->encoder->config;
tcpedit_dlt_cleanup(config->subctx);
plugin->config = NULL;
plugin->config_size = 0;
}

return TCPEDIT_OK; /* success */
Expand Down
11 changes: 6 additions & 5 deletions src/tcpedit/plugins/dlt_linuxsll/linuxsll.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,12 @@ dlt_linuxsll_init(tcpeditdlt_t *ctx)
}

/* allocate memory for our deocde extra data */
if (sizeof(linuxsll_extra_t) > 0)
ctx->decoded_extra = safe_malloc(sizeof(linuxsll_extra_t));
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 */
}
Expand All @@ -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 */
Expand Down
2 changes: 2 additions & 0 deletions src/tcpedit/plugins/dlt_null/null.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion src/tcpedit/plugins/dlt_plugins.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ tcpedit_dlt_cleanup(tcpeditdlt_t *ctx)

if (ctx->decoded_extra != NULL)
safe_free(ctx->decoded_extra);

safe_free(ctx);
}

Expand Down
2 changes: 2 additions & 0 deletions src/tcpedit/plugins/dlt_pppserial/pppserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
25 changes: 18 additions & 7 deletions src/tcpedit/plugins/dlt_radiotap/radiotap.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ dlt_radiotap_init(tcpeditdlt_t *ctx)
}

/* allocate memory for our deocde extra data */
if (sizeof(radiotap_extra_t) > 0)
ctx->decoded_extra = safe_malloc(sizeof(radiotap_extra_t));
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 */
}
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}

/*
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit 746b10a

Please sign in to comment.