mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mac80211: extend ieee80211_ie_split to support EXTENSION
Current ieee80211_ie_split() implementation doesn't account for elements that are sub-elements of the EXTENSION IE. To extend support to these IEs as well, treat the WLAN_EID_EXTENSION ids in the %ids array as indicating that the next id in the array is a sub-element of the EXTENSION IE. Signed-off-by: Liad Kaufman <liad.kaufman@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									79af1f8661
								
							
						
					
					
						commit
						2512b1b18d
					
				
					 2 changed files with 50 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -5934,7 +5934,8 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
 | 
			
		|||
 * @ies: the IE buffer
 | 
			
		||||
 * @ielen: the length of the IE buffer
 | 
			
		||||
 * @ids: an array with element IDs that are allowed before
 | 
			
		||||
 *	the split
 | 
			
		||||
 *	the split. A WLAN_EID_EXTENSION value means that the next
 | 
			
		||||
 *	EID in the list is a sub-element of the EXTENSION IE.
 | 
			
		||||
 * @n_ids: the size of the element ID array
 | 
			
		||||
 * @after_ric: array IE types that come after the RIC element
 | 
			
		||||
 * @n_after_ric: size of the @after_ric array
 | 
			
		||||
| 
						 | 
				
			
			@ -5965,7 +5966,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
 | 
			
		|||
 * @ies: the IE buffer
 | 
			
		||||
 * @ielen: the length of the IE buffer
 | 
			
		||||
 * @ids: an array with element IDs that are allowed before
 | 
			
		||||
 *	the split
 | 
			
		||||
 *	the split. A WLAN_EID_EXTENSION value means that the next
 | 
			
		||||
 *	EID in the list is a sub-element of the EXTENSION IE.
 | 
			
		||||
 * @n_ids: the size of the element ID array
 | 
			
		||||
 * @offset: offset where to start splitting in the buffer
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1367,13 +1367,29 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(cfg80211_get_p2p_attr);
 | 
			
		||||
 | 
			
		||||
static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
 | 
			
		||||
static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id, bool id_ext)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < n_ids; i++)
 | 
			
		||||
		if (ids[i] == id)
 | 
			
		||||
	/* Make sure array values are legal */
 | 
			
		||||
	if (WARN_ON(ids[n_ids - 1] == WLAN_EID_EXTENSION))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	i = 0;
 | 
			
		||||
	while (i < n_ids) {
 | 
			
		||||
		if (ids[i] == WLAN_EID_EXTENSION) {
 | 
			
		||||
			if (id_ext && (ids[i + 1] == id))
 | 
			
		||||
				return true;
 | 
			
		||||
 | 
			
		||||
			i += 2;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ids[i] == id && !id_ext)
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1403,14 +1419,36 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
 | 
			
		|||
{
 | 
			
		||||
	size_t pos = offset;
 | 
			
		||||
 | 
			
		||||
	while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) {
 | 
			
		||||
	while (pos < ielen) {
 | 
			
		||||
		u8 ext = 0;
 | 
			
		||||
 | 
			
		||||
		if (ies[pos] == WLAN_EID_EXTENSION)
 | 
			
		||||
			ext = 2;
 | 
			
		||||
		if ((pos + ext) >= ielen)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		if (!ieee80211_id_in_list(ids, n_ids, ies[pos + ext],
 | 
			
		||||
					  ies[pos] == WLAN_EID_EXTENSION))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
 | 
			
		||||
			pos = skip_ie(ies, ielen, pos);
 | 
			
		||||
 | 
			
		||||
			while (pos < ielen &&
 | 
			
		||||
			       !ieee80211_id_in_list(after_ric, n_after_ric,
 | 
			
		||||
						     ies[pos]))
 | 
			
		||||
			while (pos < ielen) {
 | 
			
		||||
				if (ies[pos] == WLAN_EID_EXTENSION)
 | 
			
		||||
					ext = 2;
 | 
			
		||||
				else
 | 
			
		||||
					ext = 0;
 | 
			
		||||
 | 
			
		||||
				if ((pos + ext) >= ielen)
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				if (!ieee80211_id_in_list(after_ric,
 | 
			
		||||
							  n_after_ric,
 | 
			
		||||
							  ies[pos + ext],
 | 
			
		||||
							  ext == 2))
 | 
			
		||||
					pos = skip_ie(ies, ielen, pos);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			pos = skip_ie(ies, ielen, pos);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue