[PATCH] Reject authentication start during BSS TM requests

Nicolas Norvez norvez at chromium.org
Tue Jan 4 17:35:13 PST 2022


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 patch is the equivalent of commit
5ac977758d3535e91160ff210f3e8a578031029d for the roaming scenario.

Signed-off-by: Nicolas Norvez <norvez at chromium.org>

---
 wpa_supplicant/sme.c              | 11 +++++++++++
 wpa_supplicant/wnm_sta.c          | 10 ++++++++++
 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 f59e02bd3..03c9e41e7 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -943,6 +943,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)
@@ -989,6 +992,14 @@ 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..f84ab0f1b 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -1097,6 +1097,7 @@ 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 +1122,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 6a82fe044..858ca23d1 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1184,6 +1184,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;
-- 
2.34.1.448.ga2b2bfdf31-goog




More information about the Hostap mailing list