diff options
author | Michael Mann <mmann78@netscape.net> | 2016-01-17 19:13:04 -0500 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2016-01-19 05:48:30 +0000 |
commit | 1c090e929269a78bf7a4cb3dc0d34565f4351312 (patch) | |
tree | bcc6bf56c8cccaf70ada081df484d0097d83929e | |
parent | 203b9e07127d418a128a743ad688344047b743c2 (diff) |
[LBMC] Bugfix stack-based buffer overflow in dissect_nhdr_extopt.
Bug: 11984
Change-Id: I16ef6e830f0377992233a1bd255c1e3877e56a55
Reviewed-on: https://code.wireshark.org/review/13375
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | epan/dissectors/packet-lbmc.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/epan/dissectors/packet-lbmc.c b/epan/dissectors/packet-lbmc.c index d1bd030c9e..8a092fe432 100644 --- a/epan/dissectors/packet-lbmc.c +++ b/epan/dissectors/packet-lbmc.c @@ -6019,6 +6019,7 @@ static expert_field ei_lbmc_analysis_no_reassembly = EI_INIT; static expert_field ei_lbmc_analysis_invalid_offset = EI_INIT; static expert_field ei_lbmc_analysis_missing_reassembly_frame = EI_INIT; static expert_field ei_lbmc_analysis_invalid_fragment = EI_INIT; +static expert_field ei_lbmc_extopt_fragment_offset = EI_INIT; /* Extended option reassembly structures. */ #define LBMC_EXTOPT_REASSEMBLED_DATA_MAX_LEN 65536 @@ -9930,7 +9931,7 @@ static int dissect_nhdr_extopt(tvbuff_t * tvb, int offset, packet_info * pinfo, NULL }; proto_item * ritem = NULL; - proto_tree * rtree = NULL; + proto_tree * rtree = NULL, *fragment_item; guint8 flags_val = 0; int len_dissected = 0; int data_len = 0; @@ -9949,7 +9950,7 @@ static int dissect_nhdr_extopt(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree_add_bitmask(subtree, tvb, offset + O_LBMC_EXTOPT_HDR_T_FLAGS, hf_lbmc_extopt_flags, ett_lbmc_extopt_flags, flags, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_lbmc_extopt_id, tvb, offset + O_LBMC_EXTOPT_HDR_T_ID, L_LBMC_EXTOPT_HDR_T_ID, ENC_BIG_ENDIAN); proto_tree_add_item(subtree, hf_lbmc_extopt_subtype, tvb, offset + O_LBMC_EXTOPT_HDR_T_SUBTYPE, L_LBMC_EXTOPT_HDR_T_SUBTYPE, ENC_BIG_ENDIAN); - proto_tree_add_item(subtree, hf_lbmc_extopt_fragment_offset, tvb, offset + O_LBMC_EXTOPT_HDR_T_FRAGMENT_OFFSET, L_LBMC_EXTOPT_HDR_T_FRAGMENT_OFFSET, ENC_BIG_ENDIAN); + fragment_item = proto_tree_add_item(subtree, hf_lbmc_extopt_fragment_offset, tvb, offset + O_LBMC_EXTOPT_HDR_T_FRAGMENT_OFFSET, L_LBMC_EXTOPT_HDR_T_FRAGMENT_OFFSET, ENC_BIG_ENDIAN); len_dissected = L_LBMC_EXTOPT_HDR_T; data_len = (int)hdrlen - len_dissected; data_offset = offset + len_dissected; @@ -9963,11 +9964,19 @@ static int dissect_nhdr_extopt(tvbuff_t * tvb, int offset, packet_info * pinfo, gchar * buf; proto_item * pi = NULL; - tvb_memcpy(tvb, reassembly->data + fragment_offset, data_offset, data_len); - reassembly->len += data_len; - buf = (gchar *) wmem_memdup(wmem_file_scope(), reassembly->data, reassembly->len); - reassembly_tvb = tvb_new_real_data(buf, reassembly->len, reassembly->len); - add_new_data_source(pinfo, reassembly_tvb, "Reassembled EXTOPT fragment data"); + if ((reassembly->len + fragment_offset + data_len) < LBMC_EXTOPT_REASSEMBLED_DATA_MAX_LEN) + { + tvb_memcpy(tvb, reassembly->data + fragment_offset, data_offset, data_len); + reassembly->len += data_len; + buf = (gchar *) wmem_memdup(wmem_file_scope(), reassembly->data, reassembly->len); + reassembly_tvb = tvb_new_real_data(buf, reassembly->len, reassembly->len); + add_new_data_source(pinfo, reassembly_tvb, "Reassembled EXTOPT fragment data"); + } + else + { + expert_add_info(pinfo, fragment_item, &ei_lbmc_extopt_fragment_offset); + return (len_dissected); + } proto_tree_add_item(subtree, hf_lbmc_extopt_data, tvb, data_offset, data_len, ENC_NA); ritem = proto_tree_add_item(tree, hf_lbmc_extopt_reassembled_data, reassembly_tvb, 0, reassembly->len, ENC_NA); rtree = proto_item_add_subtree(ritem, ett_lbmc_extopt_reassembled_data); @@ -10010,9 +10019,17 @@ static int dissect_nhdr_extopt(tvbuff_t * tvb, int offset, packet_info * pinfo, /* Self-contained extended option. */ if (reassembly->reassembly_in_progress) { - tvb_memcpy(tvb, reassembly->data + fragment_offset, data_offset, data_len); - reassembly->len += data_len; - proto_tree_add_item(subtree, hf_lbmc_extopt_data, tvb, offset + len_dissected, data_len, ENC_NA); + if ((reassembly->len + fragment_offset + data_len) < LBMC_EXTOPT_REASSEMBLED_DATA_MAX_LEN) + { + tvb_memcpy(tvb, reassembly->data + fragment_offset, data_offset, data_len); + reassembly->len += data_len; + proto_tree_add_item(subtree, hf_lbmc_extopt_data, tvb, offset + len_dissected, data_len, ENC_NA); + } + else + { + expert_add_info(pinfo, fragment_item, &ei_lbmc_extopt_fragment_offset); + return (len_dissected); + } } else { @@ -10025,8 +10042,16 @@ static int dissect_nhdr_extopt(tvbuff_t * tvb, int offset, packet_info * pinfo, } else { - tvb_memcpy(tvb, reassembly->data + fragment_offset, data_offset, data_len); - reassembly->len += data_len; + if ((reassembly->len + fragment_offset + data_len) < LBMC_EXTOPT_REASSEMBLED_DATA_MAX_LEN) + { + tvb_memcpy(tvb, reassembly->data + fragment_offset, data_offset, data_len); + reassembly->len += data_len; + } + else + { + expert_add_info(pinfo, fragment_item, &ei_lbmc_extopt_fragment_offset); + return (len_dissected); + } } proto_tree_add_item(subtree, hf_lbmc_extopt_data, tvb, data_offset, data_len, ENC_NA); } @@ -14156,7 +14181,9 @@ void proto_register_lbmc(void) { &ei_lbmc_analysis_invalid_offset, { "lbmc.analysis.invalid_offset", PI_MALFORMED, PI_ERROR, "Message property offset exceeds data length", EXPFILL } }, { &ei_lbmc_analysis_missing_reassembly_frame, { "lbmc.analysis.missing_reassembly_frame", PI_UNDECODED, PI_WARN, "Message not reassembled - reassembly data missing from capture", EXPFILL } }, { &ei_lbmc_analysis_invalid_fragment, { "lbmc.analysis.invalid_fragment", PI_MALFORMED, PI_ERROR, "Invalid fragment", EXPFILL } }, + { &ei_lbmc_extopt_fragment_offset, { "lbmc.extopt.fragment_offset.invalid", PI_PROTOCOL, PI_ERROR, "Invalid fragment offset", EXPFILL } }, }; + module_t * lbmc_module = NULL; expert_module_t * expert_lbmc; |