diff mbox

[3.5.y.z,extended,stable] Patch "mac80211: always synchronize_net() during station removal" has been added to staging queue

Message ID 1365081948-14963-1-git-send-email-luis.henriques@canonical.com
State New
Headers show

Commit Message

Luis Henriques April 4, 2013, 1:25 p.m. UTC
This is a note to let you know that I have just added a patch titled

    mac80211: always synchronize_net() during station removal

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

From e11b3abbf2494506ba5131f71374dd5ea8c45ebc Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 6 Mar 2013 23:17:08 +0100
Subject: [PATCH] mac80211: always synchronize_net() during station removal

commit 27a737ff7cb062fb9cbceba9b44d60aa74862bfa upstream.

If there are keys left during station removal, then a
synchronize_net() will be done (for each key, I have a
patch to address this for 3.10), otherwise it won't be
done at all which causes issues because the station
could be used for TX while it's being removed from the
driver -- that might confuse the driver.

Fix this by always doing synchronize_net() if no key
was present any more.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ luis: adjust context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 net/mac80211/sta_info.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

--
1.8.1.2
diff mbox

Patch

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index fec8eab..91eb0c5 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -664,6 +664,7 @@  int __must_check __sta_info_destroy(struct sta_info *sta)
 	struct ieee80211_sub_if_data *sdata;
 	int ret, i, ac;
 	struct tid_ampdu_tx *tid_tx;
+	bool have_key = false;

 	might_sleep();

@@ -691,12 +692,19 @@  int __must_check __sta_info_destroy(struct sta_info *sta)
 	list_del_rcu(&sta->list);

 	mutex_lock(&local->key_mtx);
-	for (i = 0; i < NUM_DEFAULT_KEYS; i++)
+	for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
 		__ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
-	if (sta->ptk)
+		have_key = true;
+	}
+	if (sta->ptk) {
 		__ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
+		have_key = true;
+	}
 	mutex_unlock(&local->key_mtx);

+	if (!have_key)
+		synchronize_net();
+
 	sta->dead = true;

 	local->num_sta--;