diff -u b/epan/dissectors/packet-ieee80211-radiotap-iter.c b/epan/dissectors/packet-ieee80211-radiotap-iter.c
--- b/epan/dissectors/packet-ieee80211-radiotap-iter.c
+++ b/epan/dissectors/packet-ieee80211-radiotap-iter.c
@@ -120,6 +120,9 @@
struct ieee80211_radiotap_header *radiotap_header,
int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
{
+ if (max_length < (int)sizeof(struct ieee80211_radiotap_header))
+ return -EINVAL;
+
/* Linux only supports version 0 radiotap format */
if (radiotap_header->it_version)
return -EINVAL;
@@ -131,6 +134,7 @@
iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present);
iterator->_arg = (guint8 *)radiotap_header + sizeof(*radiotap_header);
iterator->_reset_on_ext = 0;
+ iterator->_next_ns_data = NULL;
iterator->_next_bitmap = &radiotap_header->it_present;
iterator->_next_bitmap++;
iterator->_vns = vns;
@@ -146,9 +150,11 @@
/* find payload start allowing for extended bitmap(s) */
- if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) {
+ if (iterator->_bitmap_shifter & (1U<<IEEE80211_RADIOTAP_EXT)) {
+ if(!ITERATOR_VALID(iterator, sizeof(guint32)))
+ return -EINVAL;
while (get_unaligned_le32(iterator->_arg) &
- (1 << IEEE80211_RADIOTAP_EXT)) {
+ (1U << IEEE80211_RADIOTAP_EXT)) {
iterator->_arg += sizeof(guint32);
/*
@@ -157,7 +163,7 @@
* stated radiotap header length
*/
- if (!ITERATOR_VALID(iterator, 0))
+ if (!ITERATOR_VALID(iterator, sizeof(guint32)))
return -EINVAL;
}
@@ -287,9 +293,14 @@
}
if (!align) {
/* skip all subsequent data */
+ if (!iterator->_next_ns_data)
+ return -EINVAL;
iterator->_arg = iterator->_next_ns_data;
/* give up on this namespace */
iterator->current_namespace = NULL;
+ iterator->_next_ns_data = NULL;
+ if (!ITERATOR_VALID(iterator, 0))
+ return -EINVAL;
goto next_entry;
}
break;
diff --git a/epan/dissectors/packet-ieee80211-radiotap.c.old b/epan/dissectors/packet-ieee80211-radiotap.c
index fd8ad89..c4945a8 100644
--- a/epan/dissectors/packet-ieee80211-radiotap.c.old
+++ b/epan/dissectors/packet-ieee80211-radiotap.c
@@ -49,6 +49,7 @@ static int proto_radiotap = -1;
static int hf_radiotap_version = -1;
static int hf_radiotap_pad = -1;
static int hf_radiotap_length = -1;
+static int hf_radiotap_invalid_header_length = -1;
static int hf_radiotap_present = -1;
static int hf_radiotap_mactime = -1;
/* static int hf_radiotap_channel = -1; */
@@ -1024,6 +1025,14 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
tvb, 2, 2, length);
}
+ /*
+ * The length is the length of the entire radiotap header, so it
+ * must be at least 8, for the version, padding, length, and first
+ * presence flags word.
+ */
+ if (length < 8)
+ return;
+
data = ep_tvb_memdup(tvb, 0, length);
if (!data)
return;
@@ -1990,6 +1999,11 @@ void proto_register_radiotap(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
"Padding", HFILL}},
+ {&hf_radiotap_invalid_header_length,
+ {"Present flags", "radiotap.length.invalid",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ "The radiotap header length is less than 8 bytes", HFILL}},
+
{&hf_radiotap_length,
{"Header length", "radiotap.length",
FT_UINT16, BASE_DEC, NULL, 0x0,