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
 | 
					 * @ies: the IE buffer
 | 
				
			||||||
 * @ielen: the length of the IE buffer
 | 
					 * @ielen: the length of the IE buffer
 | 
				
			||||||
 * @ids: an array with element IDs that are allowed before
 | 
					 * @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
 | 
					 * @n_ids: the size of the element ID array
 | 
				
			||||||
 * @after_ric: array IE types that come after the RIC element
 | 
					 * @after_ric: array IE types that come after the RIC element
 | 
				
			||||||
 * @n_after_ric: size of the @after_ric array
 | 
					 * @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
 | 
					 * @ies: the IE buffer
 | 
				
			||||||
 * @ielen: the length of the IE buffer
 | 
					 * @ielen: the length of the IE buffer
 | 
				
			||||||
 * @ids: an array with element IDs that are allowed before
 | 
					 * @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
 | 
					 * @n_ids: the size of the element ID array
 | 
				
			||||||
 * @offset: offset where to start splitting in the buffer
 | 
					 * @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);
 | 
					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;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < n_ids; i++)
 | 
						/* Make sure array values are legal */
 | 
				
			||||||
		if (ids[i] == id)
 | 
						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;
 | 
								return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1403,14 +1419,36 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t pos = offset;
 | 
						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) {
 | 
							if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
 | 
				
			||||||
			pos = skip_ie(ies, ielen, pos);
 | 
								pos = skip_ie(ies, ielen, pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			while (pos < ielen &&
 | 
								while (pos < ielen) {
 | 
				
			||||||
			       !ieee80211_id_in_list(after_ric, n_after_ric,
 | 
									if (ies[pos] == WLAN_EID_EXTENSION)
 | 
				
			||||||
						     ies[pos]))
 | 
										ext = 2;
 | 
				
			||||||
				pos = skip_ie(ies, ielen, pos);
 | 
									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 {
 | 
							} else {
 | 
				
			||||||
			pos = skip_ie(ies, ielen, pos);
 | 
								pos = skip_ie(ies, ielen, pos);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue