aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-05-14 00:22:44 +0200
committerAnders Broman <a.broman58@gmail.com>2018-05-14 08:13:47 +0000
commit19c45892461da6f1767190c86c62dab02db8a2e3 (patch)
tree8b53ef9285272bf78b1ef62cf76668ec99c920f3
parentb10dbb861457736991943fbddb13356ff6eb4c81 (diff)
proto: handle split bits covering more than 32 bits
proto_tree_add_split_bits_item_ret_val can handle bits from an arbitrary sized buffer, as long as it covers no more than 64 bits. If the octet-aligned mask covers up to 32 bits, then this mask is also shown. If this mask was larger than 64 bits, then undefined behavior could occur, so check for that. For larger masks, instead of "= GmPRS Terminal Type: Unknown (96)", display "7 bits = GmPRS Terminal Type: Unknown (96)" instead. Bug: 13613 Change-Id: I111cf6a0705f999e42d83bfe57ac84f414946d0b Link: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1158 Reviewed-on: https://code.wireshark.org/review/27517 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/proto.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 95298bfb80..20d075098d 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -11393,13 +11393,13 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbu
guint64 crumb_mask, crumb_value;
guint8 crumb_end_bit_offset;
- DISSECTOR_ASSERT(i < 64);
crumb_value = tvb_get_bits64(tvb,
bit_offset + crumb_spec[i].crumb_bit_offset,
crumb_spec[i].crumb_bit_length,
ENC_BIG_ENDIAN);
value += crumb_value;
no_of_bits += crumb_spec[i].crumb_bit_length;
+ DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
/* The bitmask is 64 bit, left-aligned, starting at the first bit of the
octet containing the initial offset.
@@ -11415,8 +11415,13 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbu
if (crumb_end_bit_offset > mask_greatest_bit_offset) {
mask_greatest_bit_offset = crumb_end_bit_offset;
}
- composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
- composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
+ /* Currently the bitmap of the crumbs are only shown if
+ * smaller than 32 bits. Do not bother calculating the
+ * mask if it is larger than that. */
+ if (crumb_end_bit_offset <= 32) {
+ composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
+ composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
+ }
}
/* Shift left for the next segment */
value <<= crumb_spec[++i].crumb_bit_length;
@@ -11462,6 +11467,9 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbu
(guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
(guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
mask_greatest_bit_offset);
+ } else {
+ /* If the bitmask is too large, try to describe its contents. */
+ g_snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
}
switch (hf_field->type) {