From 16b5ea9e9121b6a40e2b4fadbde5894ccbcade09 Mon Sep 17 00:00:00 2001 From: Nicolas Norvez Date: Wed, 5 Jan 2022 01:35:13 +0000 Subject: [PATCH] Reject authentication start during BSS TM requests After receiving a BSS Transition Management request, wpa_supplicant_connect() will abort ongoing scans, which will cause scan results to be reported. Since the reassociate bit is set, this will trigger a connection attempt based on the aborted scan's scan results and cancel the initial connection request. This often causes wpa_supplicant to reassociate to the same AP it is currently associated to instead of the AP it was asked to transition to. Add a bss_trans_mgmt_in_progress flag to indicate that we're currently transitioning to a different AP so that we don't initiate another connection attempt based on the possibly received scan results from a scan that was in progress at the time the BSS Transition Management request was received. This is the equivalent of commit 5ac977758d35 ("Reject authentication start during explicit roam requests") for the roaming scenario. Signed-off-by: Nicolas Norvez --- wpa_supplicant/sme.c | 10 ++++++++++ wpa_supplicant/wnm_sta.c | 11 +++++++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 3 files changed, 22 insertions(+) diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 1dc7001a7..7f43216c6 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -946,6 +946,9 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit) struct wpa_supplicant *wpa_s = work->wpa_s; wpa_s->roam_in_progress = false; +#ifdef CONFIG_WNM + wpa_s->bss_trans_mgmt_in_progress = false; +#endif /* CONFIG_WNM */ if (deinit) { if (work->started) @@ -992,6 +995,13 @@ void sme_authenticate(struct wpa_supplicant *wpa_s, "SME: Reject sme_authenticate() in favor of explicit roam request"); return; } +#ifdef CONFIG_WNM + if (wpa_s->bss_trans_mgmt_in_progress) { + wpa_dbg(wpa_s, MSG_DEBUG, + "SME: Reject sme_authenticate() in favor of BSS transition management request"); + return; + } +#endif /* CONFIG_WNM */ if (radio_work_pending(wpa_s, "sme-connect")) { /* * The previous sme-connect work might no longer be valid due to diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 8a1a44690..96160dccb 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1097,6 +1097,8 @@ static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid, int after_new_scan) { + struct wpa_radio_work *already_connecting; + wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Transition to BSS " MACSTR " based on BSS Transition Management Request (old BSSID " @@ -1121,9 +1123,18 @@ static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s, return; } + already_connecting = radio_work_pending(wpa_s, "sme-connect"); wpa_s->reassociate = 1; wpa_printf(MSG_DEBUG, "WNM: Issuing connect"); wpa_supplicant_connect(wpa_s, bss, ssid); + + /* + * Indicate that a BSS transition is in progress so scan results that + * come in before the 'sme-connect' radio work gets executed do not + * override the original connection attempt. + */ + if (!already_connecting && radio_work_pending(wpa_s, "sme-connect")) + wpa_s->bss_trans_mgmt_in_progress = true; wnm_deallocate_memory(wpa_s); } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 5fa765fda..8bb8672fb 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1286,6 +1286,7 @@ struct wpa_supplicant { struct os_reltime wnm_cand_valid_until; u8 wnm_cand_from_bss[ETH_ALEN]; enum bss_trans_mgmt_status_code bss_tm_status; + bool bss_trans_mgmt_in_progress; struct wpabuf *coloc_intf_elems; u8 coloc_intf_dialog_token; u8 coloc_intf_auto_report;