diff options
author | Peter Wu <peter@lekensteyn.nl> | 2018-05-15 13:08:49 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-05-15 17:14:20 +0000 |
commit | e67283ddca70a7652b7dd41ef8883ee3278501d0 (patch) | |
tree | 3b909eca9010ea6c7f19444671b7c7ee77ced1d0 /epan/dissectors/packet-ismp.c | |
parent | 2af0e81071c2bc58ba120351bfd17d3e16461c01 (diff) |
ISMP: fix tuple decoding
EDP_TUPLE_HOLD dissection was broken due to a length parameter mixup in
v1.99.1rc0-224-g6720c80bab. The TLV length calculation was changed in
commit ed5453d892, but the only pcap I could find for which it made a
difference includes the TL lengths in the length field.
Since commit 067a076179, the IPXNET type was wrongly decoded, fixed now.
Check IPX address length to avoid a buffer overrun (read) in
get_ether_name by at most 5 bytes.
Bug: 4943
Bug: 14672
Link: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6451
Change-Id: Ia99ab15578ecae6d5a3ec22989507d64f9926933
Reviewed-on: https://code.wireshark.org/review/27554
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-ismp.c')
-rw-r--r-- | epan/dissectors/packet-ismp.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/epan/dissectors/packet-ismp.c b/epan/dissectors/packet-ismp.c index e8c8dba6d8..4b91b26ef8 100644 --- a/epan/dissectors/packet-ismp.c +++ b/epan/dissectors/packet-ismp.c @@ -236,11 +236,11 @@ dissect_ismp_edp(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *ismp guint16 num_neighbors = 0; guint16 num_tuples = 0; guint16 tuple_type = 0; - guint16 tuple_length = 0; + guint32 tuple_length = 0; gchar* ipx_addr_str; /* Set up structures needed to add the protocol subtree and manage it */ - proto_item *edp_ti, *ti; + proto_item *edp_ti; proto_tree *edp_tree; proto_item *edp_neighbors_ti; @@ -429,23 +429,27 @@ dissect_ismp_edp(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *ismp while ( (tuples_count < num_tuples) && (tvb_reported_length_remaining(tvb, offset) >= 4) ) { - tuple_length = tvb_get_ntohs(tvb, offset+2); - edp_tuples_leaf_tree = proto_tree_add_subtree_format(edp_tuples_tree, tvb, offset, tuple_length, + edp_tuples_leaf_tree = proto_tree_add_subtree_format(edp_tuples_tree, tvb, offset, 4, ett_ismp_edp_tuples_leaf, NULL, "Tuple%d", tuples_count+1); tuple_type = tvb_get_ntohs(tvb, offset); proto_tree_add_item(edp_tuples_leaf_tree, hf_ismp_tuple_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; - proto_tree_add_item(edp_tuples_leaf_tree, hf_ismp_tuple_length, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item_ret_uint(edp_tuples_leaf_tree, hf_ismp_tuple_length, tvb, offset, 2, ENC_BIG_ENDIAN, &tuple_length); + if (tuple_length < 4) { + proto_tree_add_expert(edp_tree, pinfo, &ei_ismp_malformed, tvb, offset, 2); + return; + } offset += 2; + proto_item_set_len(edp_tuples_leaf_tree, tuple_length); + tuple_length -= 4; - if (tvb_reported_length_remaining(tvb, offset) >= tuple_length) + if ((guint)tvb_reported_length_remaining(tvb, offset) >= tuple_length) { switch (tuple_type) { case EDP_TUPLE_HOLD: - ti = proto_tree_add_item(edp_tuples_leaf_tree, hf_ismp_hold_time, tvb, offset, hf_ismp_hold_time, ENC_BIG_ENDIAN); - proto_item_set_len(ti, tuple_length); + proto_tree_add_item(edp_tuples_leaf_tree, hf_ismp_hold_time, tvb, offset, tuple_length, ENC_BIG_ENDIAN); break; case EDP_TUPLE_INT_NAME: proto_tree_add_item(edp_tuples_leaf_tree, hf_ismp_interface_name, tvb, offset, tuple_length, ENC_NA|ENC_ASCII); @@ -456,8 +460,11 @@ dissect_ismp_edp(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *ismp proto_tree_add_item(edp_tuples_leaf_tree, hf_ismp_system_description, tvb, offset, tuple_length, ENC_NA|ENC_ASCII); break; case EDP_TUPLE_IPX_ADDR: - ipx_addr_str = ipx_addr_to_str(tvb_get_ntohl(tvb, offset), - tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, tuple_length-4, ENC_ASCII)); + if (tuple_length != 4+6) { + proto_tree_add_expert(edp_tree, pinfo, &ei_ismp_malformed, tvb, offset, tuple_length); + return; + } + ipx_addr_str = ipx_addr_to_str(tvb_get_ntohl(tvb, offset), tvb_get_ptr(tvb, offset+4, tuple_length-4)); proto_tree_add_string(edp_tuples_leaf_tree, hf_ismp_interface_ipx_address ,tvb, offset, tuple_length, ipx_addr_str); break; case EDP_TUPLE_UNKNOWN: |