From: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> If DEAUTH event is received while authenticating, wpas_connection_failed() is invoked cancelling the radio work. However, the flow might continue calling sme_disassoc_while_authenticating() which leaves the wpa_supplicant in the AUTHENTICATING state, thus allowing the continuation of the connection flow (without radio work protection) in case AUTH frame is received. This issue was seen during EAPOL connection, when the client starts the fast association in wpas_wps_eapol_cb, where the following race occurs: 1. DEAUTH after initial EAPOL HS 2. Start fast associate and send AUTH 3. DEAUTH event rebound from kernel -> wpas_connection_failed() is called, stopping the connect radio work 4. SCAN is started 5. AUTH is received, and the connection flow is continued without radio work protection 6. SCAN_RESULTS received in the middle of association. 7. Failure in wpa_driver_nl80211_check_bss_status due to state mismatch - > DEAUTH with reason code 2. Fix this by not calling wpas_connection_failed() in step 4, if the wpa_supplicant is in authenticating state and using SME (same conditions that result in calling sme_disassoc_while_authenticating()). Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> --- wpa_supplicant/events.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index ba30780..1058115 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2572,8 +2572,19 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; - if (wpa_s->wpa_state >= WPA_AUTHENTICATING) - wpas_connection_failed(wpa_s, bssid); + + if (wpa_s->wpa_state >= WPA_AUTHENTICATING) { + /* + * The connection shouldn't be failed if we will call + * sme_disassoc_while_authenticating, otherwise we may + * continue the connection, without radio work + * protection. + */ + if (!authenticating || + !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) + wpas_connection_failed(wpa_s, bssid); + } + wpa_sm_notify_disassoc(wpa_s->wpa); if (locally_generated) wpa_s->disconnect_reason = -reason_code; -- 1.9.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap