Commit a710c816 authored by Johannes Berg's avatar Johannes Berg

mac80211: move 4-addr sta pointer clearing before synchronize_rcu()

The pointer should be cleared before synchronize_rcu() so that the
consequently dead station won't be found by any lookups in the TX
or RX paths.

Also check that the station is actually the one being removed, the
check is not needed because each 4-addr VLAN can only have a single
station and non-4-addr VLANs always have a NULL pointer there, but
the code is clearer this way (and we avoid the memory write.)
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 1ddbbb0c
...@@ -875,6 +875,10 @@ int __must_check __sta_info_destroy(struct sta_info *sta) ...@@ -875,6 +875,10 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
drv_sta_pre_rcu_remove(local, sta->sdata, sta); drv_sta_pre_rcu_remove(local, sta->sdata, sta);
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
rcu_access_pointer(sdata->u.vlan.sta) == sta)
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
/* this always calls synchronize_net() */ /* this always calls synchronize_net() */
ieee80211_free_sta_keys(local, sta); ieee80211_free_sta_keys(local, sta);
...@@ -883,9 +887,6 @@ int __must_check __sta_info_destroy(struct sta_info *sta) ...@@ -883,9 +887,6 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
local->num_sta--; local->num_sta--;
local->sta_generation++; local->sta_generation++;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
while (sta->sta_state > IEEE80211_STA_NONE) { while (sta->sta_state > IEEE80211_STA_NONE) {
ret = sta_info_move_state(sta, sta->sta_state - 1); ret = sta_info_move_state(sta, sta->sta_state - 1);
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment