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>
This commit is contained in:
Peter Wu 2018-05-15 13:08:49 +02:00 committed by Anders Broman
parent 2af0e81071
commit e67283ddca
1 changed files with 17 additions and 10 deletions

View File

@ -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: