Commit 06d6af4e authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: flush STA queues on unauthorization

When the station is marked as no longer authorized, we shouldn't
transmit to it any longer, but in particular we shouldn't be able
to transmit to it after removing keys, which might lead to frames
being sent out unencrypted depending on the exact hardware offload
mechanism. Thus, instead of flushing only on station destruction,
which covers only some cases, always flush on unauthorization.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230928172905.d47f528829e7.I96903652c7ee0c5c66891f8b2364383da8e45a1f@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 3831f6d8
......@@ -1275,6 +1275,8 @@ static int _sta_info_move_state(struct sta_info *sta,
enum ieee80211_sta_state new_state,
bool recalc)
{
struct ieee80211_local *local = sta->local;
might_sleep();
if (sta->sta_state == new_state)
......@@ -1350,6 +1352,24 @@ static int _sta_info_move_state(struct sta_info *sta,
} else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
ieee80211_vif_dec_num_mcast(sta->sdata);
clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
/*
* If we have encryption offload, flush (station) queues
* (after ensuring concurrent TX completed) so we won't
* transmit anything later unencrypted if/when keys are
* also removed, which might otherwise happen depending
* on how the hardware offload works.
*/
if (local->ops->set_key) {
synchronize_net();
if (local->ops->flush_sta)
drv_flush_sta(local, sta->sdata, sta);
else
ieee80211_flush_queues(local,
sta->sdata,
false);
}
ieee80211_clear_fast_xmit(sta);
ieee80211_clear_fast_rx(sta);
}
......@@ -1415,18 +1435,6 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc)
WARN_ON_ONCE(ret);
}
/* Flush queues before removing keys, as that might remove them
* from hardware, and then depending on the offload method, any
* frames sitting on hardware queues might be sent out without
* any encryption at all.
*/
if (local->ops->set_key) {
if (local->ops->flush_sta)
drv_flush_sta(local, sta->sdata, sta);
else
ieee80211_flush_queues(local, sta->sdata, false);
}
/* now keys can no longer be reached */
ieee80211_free_sta_keys(local, sta);
......
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