[linux] 01/01: mac80211: fix deadlock in driver-managed RX BA session start
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Wed Oct 11 19:49:04 UTC 2017
This is an automated email from the git hooks/post-receive script.
carnil pushed a commit to branch sid
in repository linux.
commit 7c8172804ea4f4f661d21eca351ebf58a11dd0b4
Author: Salvatore Bonaccorso <carnil at debian.org>
Date: Wed Oct 11 21:21:51 2017 +0200
mac80211: fix deadlock in driver-managed RX BA session start
Thanks: Eric Côté
Closes: #878092
---
debian/changelog | 2 +
...x-deadlock-in-driver-managed-RX-BA-sessio.patch | 151 +++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 154 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index c259cf0..f0e057f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,8 @@ linux (4.13.4-2) UNRELEASED; urgency=medium
* [powerpc*] Use emergency stack for kernel TM Bad Thing program
(CVE-2017-1000255)
* [powerpc*] Fix illegal TM state in signal handler
+ * mac80211: fix deadlock in driver-managed RX BA session start.
+ Thanks to Eric Côté (Closes: #878092)
-- Ben Hutchings <ben at decadent.org.uk> Wed, 04 Oct 2017 23:14:54 +0100
diff --git a/debian/patches/bugfix/all/mac80211-fix-deadlock-in-driver-managed-RX-BA-sessio.patch b/debian/patches/bugfix/all/mac80211-fix-deadlock-in-driver-managed-RX-BA-sessio.patch
new file mode 100644
index 0000000..1a7fff9
--- /dev/null
+++ b/debian/patches/bugfix/all/mac80211-fix-deadlock-in-driver-managed-RX-BA-sessio.patch
@@ -0,0 +1,151 @@
+From: Johannes Berg <johannes.berg at intel.com>
+Date: Wed, 6 Sep 2017 15:01:42 +0200
+Subject: mac80211: fix deadlock in driver-managed RX BA session start
+Origin: https://git.kernel.org/linus/bde59c475e0883e4c4294bcd9b9c7e08ae18c828
+Bug-Debian: https://bugs.debian.org/878092
+
+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.
+
+Cc: stable at vger.kernel.org
+Fixes: 699cb58c8a52 ("mac80211: manage RX BA session offload without SKB queue")
+Reported-by: Matteo Croce <mcroce at redhat.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+ net/mac80211/agg-rx.c | 32 +++++++++++++++++++++-----------
+ net/mac80211/ht.c | 6 +++---
+ net/mac80211/ieee80211_i.h | 4 ++++
+ 3 files changed, 28 insertions(+), 14 deletions(-)
+
+diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
+index 2b36eff5d97e..2849a1fc41c5 100644
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -245,10 +245,10 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
+ ieee80211_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(struct sta_info *sta,
+ ht_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(struct sta_info *sta,
+ "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(struct sta_info *sta,
+ ht_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(struct sta_info *sta,
+ 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 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
+ __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,
+diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
+index 4cba7fca10d4..d6d0b4201e40 100644
+--- a/net/mac80211/ht.c
++++ b/net/mac80211/ht.c
+@@ -351,9 +351,9 @@ void ieee80211_ba_session_work(struct work_struct *work)
+
+ if (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))
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 2197c62a0a6e..9675814f64db 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1760,6 +1760,10 @@ 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);
+ 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,
+--
+2.15.0.rc0
+
diff --git a/debian/patches/series b/debian/patches/series
index 9a97407..01ec973 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -78,6 +78,7 @@ bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch
bugfix/all/partially-revert-usb-kconfig-using-select-for-usb_co.patch
bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch
bugfix/all/bfq-re-enable-auto-loading-when-built-as-a-module.patch
+bugfix/all/mac80211-fix-deadlock-in-driver-managed-RX-BA-sessio.patch
# Miscellaneous features
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git
More information about the Kernel-svn-changes
mailing list