diff options
author | Gerald Combs <gerald@wireshark.org> | 2021-12-28 10:35:25 -0800 |
---|---|---|
committer | Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org> | 2021-12-28 19:06:10 +0000 |
commit | a03f43645d072b7caaa9b204067095481137a2a0 (patch) | |
tree | 84d8a220206edfac402f84d4a258ebefc7a335da /epan/dissectors/packet-kafka.c | |
parent | 1810ad641d85e521fbce9be062c27c992c9e8152 (diff) |
Kafka: Be more strict when dissecting varints.
The Kafka dissector uses the return value of tvb_get_varint to advance
the packet offset in many places. If tvb_get_varint fails it returns 0,
which means our offset isn't guaranteed to advance. Stop dissection
whenever that happens. Fixes #17811.
Diffstat (limited to 'epan/dissectors/packet-kafka.c')
-rw-r--r-- | epan/dissectors/packet-kafka.c | 55 |
1 files changed, 19 insertions, 36 deletions
diff --git a/epan/dissectors/packet-kafka.c b/epan/dissectors/packet-kafka.c index 329895f811..41cfdf33c1 100644 --- a/epan/dissectors/packet-kafka.c +++ b/epan/dissectors/packet-kafka.c @@ -985,9 +985,13 @@ dissect_kafka_compact_array(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint32 len; len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &count, ENC_VARINT_PROTOBUF); - if (len == 0 || count > 0x7ffffffL) { + if (len == 0) { + expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_bad_varint); + return tvb_captured_length(tvb); + } + if(count > 0x7ffffffL) { expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_kafka_bad_array_length); - return offset; + return offset + len; } offset += len; @@ -1036,7 +1040,7 @@ dissect_kafka_varint(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info * if (len == 0) { expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - return offset; + return tvb_captured_length(tvb); } if (p_value != NULL) *p_value = value; @@ -1057,7 +1061,7 @@ dissect_kafka_varuint(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet_info if (len == 0) { expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - return offset; + return tvb_captured_length(tvb); } if (p_value != NULL) *p_value = value; @@ -1136,13 +1140,7 @@ dissect_kafka_compact_string(proto_tree *tree, int hf_item, tvbuff_t *tvb, packe if (len == 0) { pi = proto_tree_add_item(tree, hf_item, tvb, offset, 0, ENC_NA); expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - if (p_offset) { - *p_offset = 0; - } - if (p_length) { - *p_length = 0; - } - return offset; + return tvb_captured_length(tvb); } if (length == 0) { @@ -1233,13 +1231,7 @@ dissect_kafka_compact_bytes(proto_tree *tree, int hf_item, tvbuff_t *tvb, packet if (len == 0) { pi = proto_tree_add_item(tree, hf_item, tvb, offset, 0, ENC_NA); expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - if (p_offset) { - *p_offset = 0; - } - if (p_length) { - *p_length = 0; - } - return offset; + return tvb_captured_length(tvb); } if (length == 0) { @@ -1293,9 +1285,8 @@ dissect_kafka_timestamp_delta(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree pi = proto_tree_add_time(tree, hf_item, tvb, offset, len, &nstime); if (len == 0) { - //This will probably lead to a malformed packet, but it's better than not incrementing the offset - len = FT_VARINT_MAX_LEN; expert_add_info(pinfo, pi, &ei_kafka_bad_varint); + return tvb_captured_length(tvb); } return offset+len; @@ -1313,7 +1304,7 @@ dissect_kafka_offset_delta(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr pi = proto_tree_add_int64(tree, hf_item, tvb, offset, len, base_offset+val); if (len == 0) { expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - return offset; + return tvb_captured_length(tvb); } return offset+len; @@ -1389,8 +1380,7 @@ dissect_kafka_string_new(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree if (len == 0) { pi = proto_tree_add_string_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<INVALID>"); expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - len = 5; - val = 0; + return tvb_captured_length(tvb); } else if (val > 0) { // there is payload available, possibly with 0 octets proto_tree_add_item(tree, hf_item, tvb, offset+len, (gint)val, ENC_UTF_8); @@ -1450,8 +1440,7 @@ dissect_kafka_bytes_new(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, if (len == 0) { pi = proto_tree_add_bytes_format_value(tree, hf_item, tvb, offset+len, 0, NULL, "<INVALID>"); expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - len = 5; - val = 0; + return tvb_captured_length(tvb); } else if (val > 0) { // there is payload available, possibly with 0 octets proto_tree_add_item(tree, hf_item, tvb, offset+len, (gint)val, ENC_NA); @@ -1526,7 +1515,7 @@ dissect_kafka_record_headers(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree * len = tvb_get_varint(tvb, offset, 5, &count, ENC_VARINT_ZIGZAG); if (len == 0) { expert_add_info(pinfo, record_headers_ti, &ei_kafka_bad_varint); - len = 5; + return tvb_captured_length(tvb); } else if (count < -1) { // -1 means null array expert_add_info(pinfo, record_headers_ti, &ei_kafka_bad_array_length); } @@ -1560,7 +1549,7 @@ dissect_kafka_record(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, in len = tvb_get_varint(tvb, offset, 5, &size, ENC_VARINT_ZIGZAG); if (len == 0) { expert_add_info(pinfo, record_ti, &ei_kafka_bad_varint); - return offset; + return tvb_captured_length(tvb); } else if (size < 6) { expert_add_info(pinfo, record_ti, &ei_kafka_bad_record_length); return offset + len; @@ -2149,13 +2138,7 @@ dissect_kafka_tagged_field_data(proto_tree *tree, int hf_item, tvbuff_t *tvb, pa pi = proto_tree_add_item(tree, hf_item, tvb, offset+len, (gint)length, ENC_NA); if (len == 0) { expert_add_info(pinfo, pi, &ei_kafka_bad_varint); - if (p_offset) { - *p_offset = 0; - } - if (p_len) { - *p_len = 0; - } - return offset; + return tvb_captured_length(tvb); } offset = offset + len + (gint)length; @@ -2202,8 +2185,8 @@ dissect_kafka_tagged_fields(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, len = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN, &count, ENC_VARINT_PROTOBUF); if (len == 0) { expert_add_info(pinfo, subtree, &ei_kafka_bad_varint); - return offset; - } + return tvb_captured_length(tvb); + } offset += len; /* |