diff options
Diffstat (limited to 'net/wireless/radiotap.c')
| -rw-r--r-- | net/wireless/radiotap.c | 14 | 
1 files changed, 13 insertions, 1 deletions
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index dbe35e138e9..722da616438 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -15,6 +15,7 @@   */  #include <linux/kernel.h> +#include <linux/export.h>  #include <net/cfg80211.h>  #include <net/ieee80211_radiotap.h>  #include <asm/unaligned.h> @@ -40,6 +41,8 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = {  	[IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, },  	[IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, },  	[IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, }, +	[IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, }, +	[IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, },  	/*  	 * add more here as they are defined in radiotap.h  	 */ @@ -94,6 +97,10 @@ int ieee80211_radiotap_iterator_init(  	struct ieee80211_radiotap_header *radiotap_header,  	int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)  { +	/* check the radiotap header can actually be present */ +	if (max_length < sizeof(struct ieee80211_radiotap_header)) +		return -EINVAL; +  	/* Linux only supports version 0 radiotap format */  	if (radiotap_header->it_version)  		return -EINVAL; @@ -117,6 +124,10 @@ int ieee80211_radiotap_iterator_init(  	/* find payload start allowing for extended bitmap(s) */  	if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) { +		if ((unsigned long)iterator->_arg - +		    (unsigned long)iterator->_rtheader + sizeof(uint32_t) > +		    (unsigned long)iterator->_max_length) +			return -EINVAL;  		while (get_unaligned_le32(iterator->_arg) &  					(1 << IEEE80211_RADIOTAP_EXT)) {  			iterator->_arg += sizeof(uint32_t); @@ -128,7 +139,8 @@ int ieee80211_radiotap_iterator_init(  			 */  			if ((unsigned long)iterator->_arg - -			    (unsigned long)iterator->_rtheader > +			    (unsigned long)iterator->_rtheader + +			    sizeof(uint32_t) >  			    (unsigned long)iterator->_max_length)  				return -EINVAL;  		}  | 
