mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	nl80211: correct checks for NL80211_MESHCONF_HT_OPMODE value
Previously, NL80211_MESHCONF_HT_OPMODE validation rejected correct flag combinations, e.g. IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED | IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT. Doing just a range-check allows setting flags that don't exist (0x8) and invalid flag combinations. Implements some checks based on IEEE 802.11 2012 8.4.2.59 "HT Operation element". Signed-off-by: Masashi Honma <masashi.honma@gmail.com> [reword commit message, simplify a bit] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									71f2c3470f
								
							
						
					
					
						commit
						9757235f45
					
				
					 1 changed files with 31 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -5380,6 +5380,7 @@ static int nl80211_parse_mesh_config(struct genl_info *info,
 | 
			
		|||
{
 | 
			
		||||
	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
 | 
			
		||||
	u32 mask = 0;
 | 
			
		||||
	u16 ht_opmode;
 | 
			
		||||
 | 
			
		||||
#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
 | 
			
		||||
do {									    \
 | 
			
		||||
| 
						 | 
				
			
			@ -5471,9 +5472,36 @@ do {									    \
 | 
			
		|||
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
 | 
			
		||||
				  mask, NL80211_MESHCONF_RSSI_THRESHOLD,
 | 
			
		||||
				  nl80211_check_s32);
 | 
			
		||||
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16,
 | 
			
		||||
				  mask, NL80211_MESHCONF_HT_OPMODE,
 | 
			
		||||
				  nl80211_check_u16);
 | 
			
		||||
	/*
 | 
			
		||||
	 * Check HT operation mode based on
 | 
			
		||||
	 * IEEE 802.11 2012 8.4.2.59 HT Operation element.
 | 
			
		||||
	 */
 | 
			
		||||
	if (tb[NL80211_MESHCONF_HT_OPMODE]) {
 | 
			
		||||
		ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
 | 
			
		||||
 | 
			
		||||
		if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
 | 
			
		||||
				  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
 | 
			
		||||
				  IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
 | 
			
		||||
		if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
 | 
			
		||||
		    (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
 | 
			
		||||
		switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
 | 
			
		||||
		case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
 | 
			
		||||
		case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
 | 
			
		||||
			if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
 | 
			
		||||
				return -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
 | 
			
		||||
		case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
 | 
			
		||||
			if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
 | 
			
		||||
				return -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		cfg->ht_opmode = ht_opmode;
 | 
			
		||||
	}
 | 
			
		||||
	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
 | 
			
		||||
				  1, 65535, mask,
 | 
			
		||||
				  NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue