path: root/net/mac80211/sta_info.h
diff options
authorJohannes Berg <>2015-04-01 14:20:42 +0200
committerJohannes Berg <>2015-04-01 14:35:01 +0200
commit788211d81bfdf9b6a547d0530f206ba6ee76b107 (patch)
treea985d9e3d006eafe8ad6c9963333467cc9e21ee1 /net/mac80211/sta_info.h
parentf84eaa1068315409ffbef57e6fea312180787db3 (diff)
mac80211: fix RX A-MPDU session reorder timer deletion
There's an issue with the way the RX A-MPDU reorder timer is deleted that can cause a kernel crash like this: * tid_rx is removed - call_rcu(ieee80211_free_tid_rx) * station is destroyed * reorder timer fires before ieee80211_free_tid_rx() runs, accessing the station, thus potentially crashing due to the use-after-free The station deletion is protected by synchronize_net(), but that isn't enough -- ieee80211_free_tid_rx() need not have run when that returns (it deletes the timer.) We could use rcu_barrier() instead of synchronize_net(), but that's much more expensive. Instead, to fix this, add a field tracking that the session is being deleted. In this case, the only re-arming of the timer happens with the reorder spinlock held, so make that code not rearm it if the session is being deleted and also delete the timer after setting that field. This ensures the timer cannot fire after ___ieee80211_stop_rx_ba_session() returns, which fixes the problem. Cc: Signed-off-by: Johannes Berg <>
Diffstat (limited to 'net/mac80211/sta_info.h')
1 files changed, 2 insertions, 0 deletions
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 925e68fe64c7..fb0fc1302a58 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -175,6 +175,7 @@ struct tid_ampdu_tx {
* @reorder_lock: serializes access to reorder buffer, see below.
* @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and
* and ssn.
+ * @removed: this session is removed (but might have been found due to RCU)
* This structure's lifetime is managed by RCU, assignments to
* the array holding it must hold the aggregation mutex.
@@ -199,6 +200,7 @@ struct tid_ampdu_rx {
u16 timeout;
u8 dialog_token;
bool auto_seq;
+ bool removed;