Blob Blame History Raw
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,