TCPCL: Clamp and indicate lengths too large for Wireshark to handle

This fixes windows build errors reported in comments on !8541
This commit is contained in:
Brian Sipos 2022-10-19 21:59:25 -04:00 committed by João Valverde
parent b2b76c2bae
commit a81e90f39b
2 changed files with 28 additions and 20 deletions

View File

@ -531,6 +531,7 @@ static expert_field ei_invalid_magic = EI_INIT;
static expert_field ei_invalid_version = EI_INIT; static expert_field ei_invalid_version = EI_INIT;
static expert_field ei_mismatch_version = EI_INIT; static expert_field ei_mismatch_version = EI_INIT;
static expert_field ei_chdr_duplicate = EI_INIT; static expert_field ei_chdr_duplicate = EI_INIT;
static expert_field ei_length_clamped = EI_INIT;
static expert_field ei_tcpclv3_eid_length = EI_INIT; static expert_field ei_tcpclv3_eid_length = EI_INIT;
static expert_field ei_tcpclv3_invalid_msg_type = EI_INIT; static expert_field ei_tcpclv3_invalid_msg_type = EI_INIT;
@ -564,6 +565,7 @@ static ei_register_info ei_tcpcl[] = {
{&ei_invalid_version, { "tcpcl.invalid_contact_version", PI_PROTOCOL, PI_ERROR, "Protocol version not handled", EXPFILL}}, {&ei_invalid_version, { "tcpcl.invalid_contact_version", PI_PROTOCOL, PI_ERROR, "Protocol version not handled", EXPFILL}},
{&ei_mismatch_version, { "tcpcl.mismatch_contact_version", PI_PROTOCOL, PI_ERROR, "Protocol version mismatch", EXPFILL}}, {&ei_mismatch_version, { "tcpcl.mismatch_contact_version", PI_PROTOCOL, PI_ERROR, "Protocol version mismatch", EXPFILL}},
{&ei_chdr_duplicate, { "tcpcl.contact_duplicate", PI_SEQUENCE, PI_ERROR, "Duplicate Contact Header", EXPFILL}}, {&ei_chdr_duplicate, { "tcpcl.contact_duplicate", PI_SEQUENCE, PI_ERROR, "Duplicate Contact Header", EXPFILL}},
{&ei_length_clamped, { "tcpcl.length_clamped", PI_UNDECODED, PI_ERROR, "Length too large for Wireshark to handle", EXPFILL}},
{&ei_tcpclv3_eid_length, { "tcpcl.eid_length_invalid", PI_PROTOCOL, PI_ERROR, "Invalid EID Length", EXPFILL }}, {&ei_tcpclv3_eid_length, { "tcpcl.eid_length_invalid", PI_PROTOCOL, PI_ERROR, "Invalid EID Length", EXPFILL }},
{&ei_tcpclv3_invalid_msg_type, { "tcpcl.unknown_message_type", PI_UNDECODED, PI_ERROR, "Message type is unknown", EXPFILL}}, {&ei_tcpclv3_invalid_msg_type, { "tcpcl.unknown_message_type", PI_UNDECODED, PI_ERROR, "Message type is unknown", EXPFILL}},
@ -1154,10 +1156,13 @@ static void transfer_add_refuse(tcpcl_dissect_ctx_t *ctx, guint64 xfer_id,
} }
} }
static gint get_clamped_length(guint64 orig) { static gint get_clamped_length(guint64 orig, packet_info *pinfo, proto_item *item) {
gint clamped; gint clamped;
if (orig > G_MAXINT) { if (orig > G_MAXINT) {
clamped = G_MAXINT; clamped = G_MAXINT;
if (pinfo && item) {
expert_add_info(pinfo, item, &ei_length_clamped);
}
} }
else { else {
clamped = (gint) orig; clamped = (gint) orig;
@ -1177,21 +1182,22 @@ get_v3_msg_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset,
switch (conv_hdr & TCPCLV3_TYPE_MASK) switch (conv_hdr & TCPCLV3_TYPE_MASK)
{ {
case TCPCLV3_DATA_SEGMENT: case TCPCLV3_DATA_SEGMENT: {
/* get length from sdnv */ /* get length from sdnv */
bytecount = tvb_get_sdnv(tvb, offset, &len); bytecount = tvb_get_sdnv(tvb, offset, &len);
if (bytecount == 0) if (bytecount == 0) {
return 0; return 0;
}
offset += bytecount+len; const gint len_clamp = get_clamped_length(len, NULL, NULL);
offset += bytecount + len_clamp;
break; break;
}
case TCPCLV3_ACK_SEGMENT: case TCPCLV3_ACK_SEGMENT:
/* get length from sdnv */ /* get length from sdnv */
bytecount = tvb_get_sdnv(tvb, offset, &len); bytecount = tvb_get_sdnv(tvb, offset, &len);
if (bytecount == 0) if (bytecount == 0) {
return 0; return 0;
}
offset += bytecount; offset += bytecount;
break; break;
@ -1211,8 +1217,9 @@ get_v3_msg_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset,
case TCPCLV3_LENGTH: case TCPCLV3_LENGTH:
/* get length from sdnv */ /* get length from sdnv */
bytecount = tvb_get_sdnv(tvb, offset, &len); bytecount = tvb_get_sdnv(tvb, offset, &len);
if (bytecount == 0) if (bytecount == 0) {
return 0; return 0;
}
offset += bytecount; offset += bytecount;
break; break;
} }
@ -1269,7 +1276,7 @@ dissect_v3_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return 0; return 0;
} }
offset += sdnv_length; offset += sdnv_length;
const gint data_len_clamp = get_clamped_length(segment_length); const gint data_len_clamp = get_clamped_length(segment_length, pinfo, sub_item);
// implied transfer ID // implied transfer ID
xfer_id = wmem_map_lookup(ctx->tx_peer->frame_loc_to_transfer, ctx->cur_loc); xfer_id = wmem_map_lookup(ctx->tx_peer->frame_loc_to_transfer, ctx->cur_loc);
@ -1311,7 +1318,7 @@ dissect_v3_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_get_parent_tree(tree) proto_tree_get_parent_tree(tree)
); );
} }
offset += segment_length; offset += data_len_clamp;
break; break;
} }
@ -1455,7 +1462,7 @@ static guint get_v4_msg_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset,
} }
guint64 data_len = tvb_get_guint64(tvb, offset, ENC_BIG_ENDIAN); guint64 data_len = tvb_get_guint64(tvb, offset, ENC_BIG_ENDIAN);
offset += 8; offset += 8;
const gint data_len_clamp = get_clamped_length(data_len); const gint data_len_clamp = get_clamped_length(data_len, NULL, NULL);
offset += data_len_clamp; offset += data_len_clamp;
break; break;
} }
@ -1722,7 +1729,7 @@ dissect_v4_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (data_len > ctx->rx_peer->segment_mru) { if (data_len > ctx->rx_peer->segment_mru) {
expert_add_info(pinfo, item_len, &ei_tcpclv4_xfer_seg_over_seg_mru); expert_add_info(pinfo, item_len, &ei_tcpclv4_xfer_seg_over_seg_mru);
} }
const gint data_len_clamp = get_clamped_length(data_len); const gint data_len_clamp = get_clamped_length(data_len, pinfo, item_len);
// Treat data as payload layer // Treat data as payload layer
const gint data_offset = offset; const gint data_offset = offset;
@ -1893,17 +1900,18 @@ static guint get_message_len(packet_info *pinfo, tvbuff_t *tvb, int ext_offset,
guint offset = ext_offset; guint offset = ext_offset;
if (ctx->is_contact) { if (ctx->is_contact) {
offset += 4; offset += sizeof(magic);
guint8 version = tvb_get_guint8(tvb, offset); guint8 version = tvb_get_guint8(tvb, offset);
offset += 1; offset += 1;
if (version == 3) { if (version == 3) {
offset += 3; // flags + keepalive offset += 3; // flags + keepalive
guint64 len; guint64 eid_len;
guint bytecount = tvb_get_sdnv(tvb, offset, &len); const guint bytecount = tvb_get_sdnv(tvb, offset, &eid_len);
offset += bytecount+len; const gint len_clamp = get_clamped_length(eid_len, NULL, NULL);
offset += bytecount + len_clamp;
} }
else if (version == 4) { else if (version == 4) {
offset += 1; offset += 1; // flags
} }
else { else {
return 0; return 0;
@ -2011,7 +2019,7 @@ static gint dissect_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return 0; return 0;
} }
offset += sdnv_length; offset += sdnv_length;
const gint eid_len_clamp = get_clamped_length(eid_length); const gint eid_len_clamp = get_clamped_length(eid_length, pinfo, sub_item);
proto_tree_add_item(tree_chdr, hf_tcpclv3_chdr_local_eid, tvb, offset, eid_len_clamp, ENC_NA|ENC_ASCII); proto_tree_add_item(tree_chdr, hf_tcpclv3_chdr_local_eid, tvb, offset, eid_len_clamp, ENC_NA|ENC_ASCII);
offset += eid_len_clamp; offset += eid_len_clamp;

View File

@ -4571,7 +4571,7 @@ tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const
for (i = 0; ((i < FT_VARINT_MAX_LEN) && (i < maxlen)); ++i) { for (i = 0; ((i < FT_VARINT_MAX_LEN) && (i < maxlen)); ++i) {
b = tvb_get_guint8(tvb, offset++); b = tvb_get_guint8(tvb, offset++);
if ((i == 9) && (*value >= 1ul<<(64-7))) { if ((i == 9) && (*value >= (uint64_t)1<<(64-7))) {
// guaranteed overflow, not valid SDNV // guaranteed overflow, not valid SDNV
return 0; return 0;
} }