ecc5e491207594c35995b3c80701cef00b5fb8f6
[oweals/openwrt.git] /
1 From: Johannes Berg <johannes.berg@intel.com>
2 Date: Mon, 20 Nov 2017 17:01:44 +0100
3 Subject: [PATCH] mac80211: properly free requested-but-not-started TX agg
4  sessions
5
6 When deleting a station or otherwise tearing down all aggregation
7 sessions, make sure to delete requested but not yet started ones,
8 to avoid the following scenario:
9
10  * session is requested, added to tid_start_tx[]
11  * ieee80211_ba_session_work() runs, gets past BLOCK_BA check
12  * ieee80211_sta_tear_down_BA_sessions() runs, locks &sta->ampdu_mlme.mtx,
13    e.g. while deleting the station - deleting all active sessions
14  * ieee80211_ba_session_work() continues since tear down flushes it, and
15    calls ieee80211_tx_ba_session_handle_start() for the new session, arms
16    the timer for it
17  * station deletion continues to __cleanup_single_sta() and frees the
18    session struct, while the timer is armed
19
20 Reported-by: Fengguang Wu <fengguang.wu@intel.com>
21 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
22 ---
23
24 --- a/net/mac80211/agg-tx.c
25 +++ b/net/mac80211/agg-tx.c
26 @@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(stru
27  
28         spin_lock_bh(&sta->lock);
29  
30 +       /* free struct pending for start, if present */
31 +       tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
32 +       kfree(tid_tx);
33 +       sta->ampdu_mlme.tid_start_tx[tid] = NULL;
34 +
35         tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
36         if (!tid_tx) {
37                 spin_unlock_bh(&sta->lock);