Commit 5fba4af3 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

cfg80211: avoid sending spurious deauth to userspace

Before
  commit ca9034592823e8179511e48a78731f95bfdd766c
  Author: Holger Schurig <hs4233@mail.mn-solutions.de>
  Date:   Tue Oct 13 13:45:28 2009 +0200

      cfg80211: remove warning in deauth case

we assumed that drivers never give us spurious deauth
frames because they filter them out based on the auth
state they keep track of. This turned out to be racy,
because userspace might deauth while the AP is also
sending a deauth frame, so the warning was removed.

However, in that case we should not tell userspace
about the AP's frame if it requested deauth "first",
where "first" means it came to cfg80211 first.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f38fd12f
...@@ -137,22 +137,23 @@ void __cfg80211_send_deauth(struct net_device *dev, ...@@ -137,22 +137,23 @@ void __cfg80211_send_deauth(struct net_device *dev,
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
const u8 *bssid = mgmt->bssid; const u8 *bssid = mgmt->bssid;
int i; int i;
bool found = false;
ASSERT_WDEV_LOCK(wdev); ASSERT_WDEV_LOCK(wdev);
nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
if (wdev->current_bss && if (wdev->current_bss &&
memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
cfg80211_unhold_bss(wdev->current_bss); cfg80211_unhold_bss(wdev->current_bss);
cfg80211_put_bss(&wdev->current_bss->pub); cfg80211_put_bss(&wdev->current_bss->pub);
wdev->current_bss = NULL; wdev->current_bss = NULL;
found = true;
} else for (i = 0; i < MAX_AUTH_BSSES; i++) { } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
if (wdev->auth_bsses[i] && if (wdev->auth_bsses[i] &&
memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
cfg80211_unhold_bss(wdev->auth_bsses[i]); cfg80211_unhold_bss(wdev->auth_bsses[i]);
cfg80211_put_bss(&wdev->auth_bsses[i]->pub); cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
wdev->auth_bsses[i] = NULL; wdev->auth_bsses[i] = NULL;
found = true;
break; break;
} }
if (wdev->authtry_bsses[i] && if (wdev->authtry_bsses[i] &&
...@@ -160,10 +161,16 @@ void __cfg80211_send_deauth(struct net_device *dev, ...@@ -160,10 +161,16 @@ void __cfg80211_send_deauth(struct net_device *dev,
cfg80211_unhold_bss(wdev->authtry_bsses[i]); cfg80211_unhold_bss(wdev->authtry_bsses[i]);
cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
wdev->authtry_bsses[i] = NULL; wdev->authtry_bsses[i] = NULL;
found = true;
break; break;
} }
} }
if (!found)
return;
nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
if (wdev->sme_state == CFG80211_SME_CONNECTED) { if (wdev->sme_state == CFG80211_SME_CONNECTED) {
u16 reason_code; u16 reason_code;
bool from_ap; bool from_ap;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment