aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ismp.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-05-15 13:08:49 +0200
committerAnders Broman <a.broman58@gmail.com>2018-05-15 17:14:20 +0000
commite67283ddca70a7652b7dd41ef8883ee3278501d0 (patch)
tree3b909eca9010ea6c7f19444671b7c7ee77ced1d0 /epan/dissectors/packet-ismp.c
parent2af0e81071c2bc58ba120351bfd17d3e16461c01 (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.c27
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: