Patch "mac80211: fix deadlock in driver-managed RX BA session start" has been added to the 4.13-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
mac80211: fix deadlock in driver-managed RX BA session start
to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mac80211-fix-deadlock-in-driver-managed-rx-ba-session-start.patch
and it can be found in the queue-4.13 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
bde59c475e0883e4c4294bcd9b9c7e08ae18c828Mon Sep 17 00:00:00 2001
From: Johannes Berg <[email protected]>
Date: Wed, 6 Sep 2017 15:01:42 +0200
Subject: mac80211: fix deadlock in driver-managed RX BA session start
From: Johannes Berg <[email protected]>
commit bde59c475e0883e4c4294bcd9b9c7e08ae18c828 upstream.
When an RX BA session is started by the driver, and it has to tell mac80211 about it, the corresponding bit in tid_rx_manage_offl gets set and the BA session work is scheduled. Upon testing this bit, it will call __ieee80211_start_rx_ba_session(), thus deadlocking as it already holds the ampdu_mlme.mtx, which that acquires again.
Fix this by adding ___ieee80211_start_rx_ba_session(), a version of the function that requires the mutex already held.
--- net/mac80211/agg-rx.c | 32 +++++++++++++++++++++----------- net/mac80211/ht.c | 6 +++--- net/mac80211/ieee80211_i.h | 4 ++++ 3 files changed, 28 insertions(+), 14 deletions(-)
net/mac80211/agg-rx.c +21 -11
@@ -245,10 +245,10 @@ static void ieee80211_send_addba_resp(stieee80211_tx_skb (sdata, skb); } -void __ieee80211_start_rx_ba_session (struct sta_info *sta, -u8 dialog_token,u16 timeout, -u16 start_seq_num,u16 ba_policy,u16 tid, -u16 buf_size,bool tx,bool auto_seq) +void ___ieee80211_start_rx_ba_session (struct sta_info *sta, +u8 dialog_token,u16 timeout, +u16 start_seq_num,u16 ba_policy,u16 tid, +u16 buf_size,bool tx,bool auto_seq) {struct ieee80211_local *local = sta->sdata->local;struct tid_ampdu_rx *tid_agg_rx;
@@ -267,7 +267,7 @@ void __ieee80211_start_rx_ba_session(strht_dbg (sta->sdata,"STA %pM requests BA session on unsupported tid %d\n" , sta->sta.addr, tid); - goto end_no_lock; + goto end; }if (!sta->sta.ht_cap.ht_supported) {
@@ -275,14 +275,14 @@ void __ieee80211_start_rx_ba_session(str"STA %pM erroneously requests BA session on tid %d w/o QoS\n" , sta->sta.addr, tid);/* send a response anyway, it's an error case if we get here */ - goto end_no_lock; + goto end; }if (test_sta_flag (sta,WLAN_STA_BLOCK_BA )) {ht_dbg (sta->sdata,"Suspend in progress - Denying ADDBA request (%pM tid %d)\n" , sta->sta.addr, tid); - goto end_no_lock; + goto end; }/* sanity check for incoming parameters:
@@ -296,7 +296,7 @@ void __ieee80211_start_rx_ba_session(strht_dbg_ratelimited (sta->sdata,"AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n" , sta->sta.addr, tid, ba_policy, buf_size); - goto end_no_lock; + goto end; }/* determine default buffer size */ if (buf_size ==0 )
@@ -311,7 +311,7 @@ void __ieee80211_start_rx_ba_session(str buf_size, sta->sta.addr);/* examine state machine */ -mutex_lock (&sta->ampdu_mlme.mtx); +lockdep_assert_held (&sta->ampdu_mlme.mtx);if (test_bit (tid, sta->ampdu_mlme.agg_session_valid)) {if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) {
@@ -415,15 +415,25 @@ end:__clear_bit (tid, sta->ampdu_mlme.unexpected_agg); sta->ampdu_mlme.tid_rx_token[tid] = dialog_token; } -mutex_unlock (&sta->ampdu_mlme.mtx); -end_no_lock:if (tx)ieee80211_send_addba_resp (sta->sdata, sta->sta.addr, tid, dialog_token, status,1 , buf_size, timeout); } +void __ieee80211_start_rx_ba_session (struct sta_info *sta, +u8 dialog_token,u16 timeout, +u16 start_seq_num,u16 ba_policy,u16 tid, +u16 buf_size,bool tx,bool auto_seq) +{ +mutex_lock (&sta->ampdu_mlme.mtx); +___ieee80211_start_rx_ba_session (sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, tx, auto_seq); +mutex_unlock (&sta->ampdu_mlme.mtx); +} + void ieee80211_process_addba_request(struct ieee80211_local *local, struct sta_info *sta, struct ieee80211_mgmt *mgmt,
net/mac80211/ht.c +3 -3
@@ -333,9 +333,9 @@ void ieee80211_ba_session_work(struct woif (test_and_clear_bit (tid, sta->ampdu_mlme.tid_rx_manage_offl)) -__ieee80211_start_rx_ba_session (sta,0 ,0 ,0 ,1 , tid, -IEEE80211_MAX_AMPDU_BUF , - false, true); +___ieee80211_start_rx_ba_session (sta,0 ,0 ,0 ,1 , tid, +IEEE80211_MAX_AMPDU_BUF , + false, true);if (test_and_clear_bit (tid +IEEE80211_NUM_TIDS , sta->ampdu_mlme.tid_rx_manage_offl))
net/mac80211/ieee80211_i.h +4 -0
@@ -1760,6 +1760,10 @@ void __ieee80211_start_rx_ba_session(str u8 dialog_token, u16 timeout, u16 start_seq_num, u16 ba_policy, u16 tid, u16 buf_size, bool tx, bool auto_seq); +void ___ieee80211_start_rx_ba_session (struct sta_info *sta, +u8 dialog_token,u16 timeout, +u16 start_seq_num,u16 ba_policy,u16 tid, +u16 buf_size,bool tx,bool auto_seq);void ieee80211_sta_tear_down_BA_sessions (struct sta_info *sta,enum ieee80211_agg_stop_reason reason); void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/mac80211-fix-deadlock-in-driver-managed-rx-ba-session-start.patch queue-4.13/mac80211-flush-hw_roc_start-work-before-cancelling-the-roc.patch queue-4.13/mac80211_hwsim-use-proper-tx-power.patch queue-4.13/mac80211-fix-vlan-handling-with-txqs.patch