mac80211: Fix race between ieee80211_rx_bss_put and lookup routines.
Subsystems (3)
PATCH 1/1 mac80211: Fix race between ieee80211_rx_bss_put and lookup routines.
The put routine first decrements the users counter and then (if it is zero) locks the sta_bss_lock and removes one from the list and the hash.
Thus, any of ieee80211_sta_config_auth, ieee80211_rx_bss_get or ieee80211_rx_mesh_bss_get can race with it by finding a bss that is about to get kfree-ed.
Using atomic_dec_and_lock in ieee80211_rx_bss_put takes care of this race.
---
net/mac80211/mlme.c +5 -2
@@ -2248,10 +2248,13 @@ static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr); -if (!atomic_dec_and_test (&bss->users)) + +local_bh_disable (); +if (!atomic_dec_and_lock (&bss->users, &local->sta_bss_lock)) { +local_bh_enable ();return ; + } -spin_lock_bh (&local->sta_bss_lock);__ieee80211_rx_bss_hash_del (dev, bss);list_del (&bss->list);spin_unlock_bh (&local->sta_bss_lock);
A message that is not in the archive (sent off-list or not yet received): [email protected]
Johannes Berg
Acked-byQuoted 10 lines · Pavel Emelyanov
The put routine first decrements the users counter and then (if it is zero) locks the
sta_bss_lockand removes one from the list and the hash.Thus, any of
ieee80211_sta_config_auth,ieee80211_rx_bss_getorieee80211_rx_mesh_bss_getcan race with it by finding a bss that is about to get kfree-ed.Using
atomic_dec_and_lockinieee80211_rx_bss_puttakes care of this race.
Good catch, thanks.
Quoted 1 line
Signed-off-by Pavel Emelyanov <[email protected]>
I think we will need this in -stable (different file, same contents)
Quoted 23 lines
---
net/mac80211/mlme.c +5
-2@@ -2248,10 +2248,13 @@ static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr); -if (!atomic_dec_and_test (&bss->users)) + +local_bh_disable (); +if (!atomic_dec_and_lock (&bss->users, &local->sta_bss_lock)) { +local_bh_enable ();return ; + } -spin_lock_bh (&local->sta_bss_lock);__ieee80211_rx_bss_hash_del (dev, bss);list_del (&bss->list);spin_unlock_bh (&local->sta_bss_lock);