mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	wifi: mac80211: don't connect to an AP while it's in a CSA process
Connection to an AP that is running a CSA flow may end up with a failure as the AP might change its channel during the connection flow while we do not track the channel change yet. Avoid that by rejecting a connection to such an AP. Signed-off-by: Ayala Beker <ayala.beker@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230920211508.e5001a762a4a.I9745c695f3403b259ad000ce94110588a836c04a@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									2bf57b00ab
								
							
						
					
					
						commit
						c09c4f3199
					
				
					 1 changed files with 33 additions and 1 deletions
				
			
		| 
						 | 
					@ -7015,6 +7015,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 | 
						struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 | 
				
			||||||
	struct ieee80211_mgd_auth_data *auth_data;
 | 
						struct ieee80211_mgd_auth_data *auth_data;
 | 
				
			||||||
	struct ieee80211_link_data *link;
 | 
						struct ieee80211_link_data *link;
 | 
				
			||||||
 | 
						const struct element *csa_elem, *ecsa_elem;
 | 
				
			||||||
	u16 auth_alg;
 | 
						u16 auth_alg;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	bool cont_auth;
 | 
						bool cont_auth;
 | 
				
			||||||
| 
						 | 
					@ -7057,6 +7058,22 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
	if (ifmgd->assoc_data)
 | 
						if (ifmgd->assoc_data)
 | 
				
			||||||
		return -EBUSY;
 | 
							return -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rcu_read_lock();
 | 
				
			||||||
 | 
						csa_elem = ieee80211_bss_get_elem(req->bss, WLAN_EID_CHANNEL_SWITCH);
 | 
				
			||||||
 | 
						ecsa_elem = ieee80211_bss_get_elem(req->bss,
 | 
				
			||||||
 | 
										   WLAN_EID_EXT_CHANSWITCH_ANN);
 | 
				
			||||||
 | 
						if ((csa_elem &&
 | 
				
			||||||
 | 
						     csa_elem->datalen == sizeof(struct ieee80211_channel_sw_ie) &&
 | 
				
			||||||
 | 
						     ((struct ieee80211_channel_sw_ie *)csa_elem->data)->count != 0) ||
 | 
				
			||||||
 | 
						    (ecsa_elem &&
 | 
				
			||||||
 | 
						     ecsa_elem->datalen == sizeof(struct ieee80211_ext_chansw_ie) &&
 | 
				
			||||||
 | 
						     ((struct ieee80211_ext_chansw_ie *)ecsa_elem->data)->count != 0)) {
 | 
				
			||||||
 | 
							rcu_read_unlock();
 | 
				
			||||||
 | 
							sdata_info(sdata, "AP is in CSA process, reject auth\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rcu_read_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
 | 
						auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
 | 
				
			||||||
			    req->ie_len, GFP_KERNEL);
 | 
								    req->ie_len, GFP_KERNEL);
 | 
				
			||||||
	if (!auth_data)
 | 
						if (!auth_data)
 | 
				
			||||||
| 
						 | 
					@ -7364,7 +7381,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
	struct ieee80211_local *local = sdata->local;
 | 
						struct ieee80211_local *local = sdata->local;
 | 
				
			||||||
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 | 
						struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 | 
				
			||||||
	struct ieee80211_mgd_assoc_data *assoc_data;
 | 
						struct ieee80211_mgd_assoc_data *assoc_data;
 | 
				
			||||||
	const struct element *ssid_elem;
 | 
						const struct element *ssid_elem, *csa_elem, *ecsa_elem;
 | 
				
			||||||
	struct ieee80211_vif_cfg *vif_cfg = &sdata->vif.cfg;
 | 
						struct ieee80211_vif_cfg *vif_cfg = &sdata->vif.cfg;
 | 
				
			||||||
	ieee80211_conn_flags_t conn_flags = 0;
 | 
						ieee80211_conn_flags_t conn_flags = 0;
 | 
				
			||||||
	struct ieee80211_link_data *link;
 | 
						struct ieee80211_link_data *link;
 | 
				
			||||||
| 
						 | 
					@ -7394,6 +7411,21 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
		kfree(assoc_data);
 | 
							kfree(assoc_data);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						csa_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_CHANNEL_SWITCH);
 | 
				
			||||||
 | 
						ecsa_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_EXT_CHANSWITCH_ANN);
 | 
				
			||||||
 | 
						if ((csa_elem &&
 | 
				
			||||||
 | 
						     csa_elem->datalen == sizeof(struct ieee80211_channel_sw_ie) &&
 | 
				
			||||||
 | 
						     ((struct ieee80211_channel_sw_ie *)csa_elem->data)->count != 0) ||
 | 
				
			||||||
 | 
						    (ecsa_elem &&
 | 
				
			||||||
 | 
						     ecsa_elem->datalen == sizeof(struct ieee80211_ext_chansw_ie) &&
 | 
				
			||||||
 | 
						     ((struct ieee80211_ext_chansw_ie *)ecsa_elem->data)->count != 0)) {
 | 
				
			||||||
 | 
							sdata_info(sdata, "AP is in CSA process, reject assoc\n");
 | 
				
			||||||
 | 
							rcu_read_unlock();
 | 
				
			||||||
 | 
							kfree(assoc_data);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(assoc_data->ssid, ssid_elem->data, ssid_elem->datalen);
 | 
						memcpy(assoc_data->ssid, ssid_elem->data, ssid_elem->datalen);
 | 
				
			||||||
	assoc_data->ssid_len = ssid_elem->datalen;
 | 
						assoc_data->ssid_len = ssid_elem->datalen;
 | 
				
			||||||
	memcpy(vif_cfg->ssid, assoc_data->ssid, assoc_data->ssid_len);
 | 
						memcpy(vif_cfg->ssid, assoc_data->ssid, assoc_data->ssid_len);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue