]>
Commit | Line | Data |
---|---|---|
80e6ae8f GKH |
1 | From 3bdb2d48c5f58c781a4099c99044384a23620884 Mon Sep 17 00:00:00 2001 |
2 | From: Johannes Berg <johannes@sipsolutions.net> | |
3 | Date: Wed, 23 Dec 2009 13:12:05 +0100 | |
4 | Subject: cfg80211: fix race between deauth and assoc response | |
5 | ||
6 | From: Johannes Berg <johannes@sipsolutions.net> | |
7 | ||
8 | commit 3bdb2d48c5f58c781a4099c99044384a23620884 upstream. | |
9 | ||
10 | Joseph Nahmias reported, in http://bugs.debian.org/562016, | |
11 | that he was getting the following warning (with some log | |
12 | around the issue): | |
13 | ||
14 | ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1) | |
15 | ath0: direct probe responded | |
16 | ath0: authenticate with AP 00:11:95:77:e0:b0 (try 1) | |
17 | ath0: authenticated | |
18 | ath0: associate with AP 00:11:95:77:e0:b0 (try 1) | |
19 | ath0: deauthenticating from 00:11:95:77:e0:b0 by local choice (reason=3) | |
20 | ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1) | |
21 | ath0: RX AssocResp from 00:11:95:77:e0:b0 (capab=0x421 status=0 aid=2) | |
22 | ath0: associated | |
23 | ------------[ cut here ]------------ | |
24 | WARNING: at net/wireless/mlme.c:97 cfg80211_send_rx_assoc+0x14d/0x152 [cfg80211]() | |
25 | Hardware name: 7658CTO | |
26 | ... | |
27 | Pid: 761, comm: phy0 Not tainted 2.6.32-trunk-686 #1 | |
28 | Call Trace: | |
29 | [<c1030a5d>] ? warn_slowpath_common+0x5e/0x8a | |
30 | [<c1030a93>] ? warn_slowpath_null+0xa/0xc | |
31 | [<f86cafc7>] ? cfg80211_send_rx_assoc+0x14d/0x152 | |
32 | ... | |
33 | ath0: link becomes ready | |
34 | ath0: deauthenticating from 00:11:95:77:e0:b0 by local choice (reason=3) | |
35 | ath0: no IPv6 routers present | |
36 | ath0: link is not ready | |
37 | ath0: direct probe to AP 00:11:95:77:e0:b0 (try 1) | |
38 | ath0: direct probe responded | |
39 | ath0: authenticate with AP 00:11:95:77:e0:b0 (try 1) | |
40 | ath0: authenticated | |
41 | ath0: associate with AP 00:11:95:77:e0:b0 (try 1) | |
42 | ath0: RX ReassocResp from 00:11:95:77:e0:b0 (capab=0x421 status=0 aid=2) | |
43 | ath0: associated | |
44 | ||
45 | It is not clear to me how the first "direct probe" here | |
46 | happens, but this seems to be a race condition, if the | |
47 | user requests to deauth after requesting assoc, but before | |
48 | the assoc response is received. In that case, it may | |
49 | happen that mac80211 tries to report the assoc success to | |
50 | cfg80211, but gets blocked on the wdev lock that is held | |
51 | because the user is requesting the deauth. | |
52 | ||
53 | The result is that we run into a warning. This is mostly | |
54 | harmless, but maybe cause an unexpected event to be sent | |
55 | to userspace; we'd send an assoc success event although | |
56 | userspace was no longer expecting that. | |
57 | ||
58 | To fix this, remove the warning and check whether the | |
59 | race happened and in that case abort processing. | |
60 | ||
61 | Reported-by: Joseph Nahmias <joe@nahmias.net> | |
62 | Cc: 562016-quiet@bugs.debian.org | |
63 | Signed-off-by: Johannes Berg <johannes@sipsolutions.net> | |
64 | Signed-off-by: John W. Linville <linville@tuxdriver.com> | |
65 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
66 | ||
67 | --- | |
68 | net/wireless/mlme.c | 13 ++++++++++++- | |
69 | 1 file changed, 12 insertions(+), 1 deletion(-) | |
70 | ||
71 | --- a/net/wireless/mlme.c | |
72 | +++ b/net/wireless/mlme.c | |
73 | @@ -94,7 +94,18 @@ void cfg80211_send_rx_assoc(struct net_d | |
74 | } | |
75 | } | |
76 | ||
77 | - WARN_ON(!bss); | |
78 | + /* | |
79 | + * We might be coming here because the driver reported | |
80 | + * a successful association at the same time as the | |
81 | + * user requested a deauth. In that case, we will have | |
82 | + * removed the BSS from the auth_bsses list due to the | |
83 | + * deauth request when the assoc response makes it. If | |
84 | + * the two code paths acquire the lock the other way | |
85 | + * around, that's just the standard situation of a | |
86 | + * deauth being requested while connected. | |
87 | + */ | |
88 | + if (!bss) | |
89 | + goto out; | |
90 | } else if (wdev->conn) { | |
91 | cfg80211_sme_failed_assoc(wdev); | |
92 | need_connect_result = false; |