Fix bogus tvbuffs to make sure reported length >= captured length.

A reported length less than a captured length is bogus, as you cannot
capture more data than there is in a packet.

Fixes #18313.
This commit is contained in:
Guy Harris 2022-09-03 03:24:33 -07:00
parent e76ebbdecc
commit 022dfd56f3
4 changed files with 42 additions and 5 deletions

View File

@ -576,6 +576,9 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
wtap_block_foreach_option(fr_data->pkt_block, frame_add_comment, (void *)&fr_user_data);
}
cap_len = tvb_captured_length(tvb);
frame_len = tvb_reported_length(tvb);
/* if FRAME is not referenced from any filters we don't need to worry about
generating any tree items. */
if (!proto_field_is_referenced(tree, proto_frame)) {
@ -586,9 +589,6 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
}
} else {
/* Put in frame header information. */
cap_len = tvb_captured_length(tvb);
frame_len = tvb_reported_length(tvb);
cap_plurality = plurality(cap_len, "", "s");
frame_plurality = plurality(frame_len, "", "s");
@ -861,8 +861,14 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
item = proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
0, 0, frame_len, "Frame Length: %u byte%s (%u bits)",
frame_len, frame_plurality, frame_len * 8);
if (frame_len < cap_len)
if (frame_len < cap_len) {
/*
* A reported length less than a captured length
* is bogus, as you cannot capture more data
* than there is in a packet.
*/
expert_add_info(pinfo, item, &ei_len_lt_caplen);
}
proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
0, 0, cap_len, "Capture Length: %u byte%s (%u bits)",
@ -930,6 +936,15 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
return tvb_captured_length(tvb);
}
if (frame_len < cap_len) {
/*
* Fix the reported length; a reported length less than
* a captured length is bogus, as you cannot capture
* more data than there is in a packet.
*/
tvb_fix_reported_length(tvb);
}
/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
TRY {
#ifdef _MSC_VER

View File

@ -806,6 +806,21 @@ tvb_set_reported_length(tvbuff_t *tvb, const guint reported_length)
tvb->contained_length = reported_length;
}
/* Repair a tvbuff where the captured length is greater than the
* reported length; such a tvbuff makes no sense, as it's impossible
* to capture more data than is in the packet.
*/
void
tvb_fix_reported_length(tvbuff_t *tvb)
{
DISSECTOR_ASSERT(tvb && tvb->initialized);
DISSECTOR_ASSERT(tvb->reported_length < tvb->length);
tvb->reported_length = tvb->length;
if (tvb->contained_length < tvb->length)
tvb->contained_length = tvb->length;
}
guint
tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
{

View File

@ -268,9 +268,15 @@ WS_DLL_PUBLIC guint tvb_ensure_reported_length_remaining(const tvbuff_t *tvb,
dissector's payload may include padding as well as the packet for
this protocol.
Also adjusts the data length. */
Also adjusts the available and contained length. */
WS_DLL_PUBLIC void tvb_set_reported_length(tvbuff_t *tvb, const guint);
/* Repair a tvbuff where the captured length is greater than the
* reported length; such a tvbuff makes no sense, as it's impossible
* to capture more data than is in the packet.
*/
WS_DLL_PUBLIC void tvb_fix_reported_length(tvbuff_t *tvb);
WS_DLL_PUBLIC guint tvb_offset_from_real_beginning(const tvbuff_t *tvb);
/* Returns the offset from the first byte of real data. */

View File

@ -1803,6 +1803,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
tvb_find_line_end@Base 1.9.1
tvb_find_line_end_unquoted@Base 1.9.1
tvb_find_tvb@Base 1.9.1
tvb_fix_reported_length@Base 4.0.0-rc2
tvb_format_text@Base 1.9.1
tvb_format_text_wsp@Base 1.9.1
tvb_free@Base 1.9.1