CHROMIUM: wpa_supplicant: reject auths during explicit roam requests

The roam D-Bus and wpa_cli commands flip the reassociate bit before
calling wpa_supplicant_connect. wpa_supplicant connect eventually aborts
ongoing scans, which causes 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 connetion
request. This often causes wpa_supplicant to reassociate to the same AP
it is currently associated to.

Add a roam_in_progress flag to indicate that we're currently attempting
to roam via D-Bus so that we don't initate another connection attempt.

BUG=b:179389661
TEST=wifi.RoamDbus with a scan right before roam request

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
Change-Id: I70d358ee1cb9b09c4d91f0eedbb69675a0a65c02
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/hostap/+/2683454
Tested-by: Brian Norris <briannorris@chromium.org>
Reviewed-by: Brian Norris <briannorris@chromium.org>
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 847093f..efdb855 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5286,6 +5286,15 @@
 	wpa_s->reassociate = 1;
 	wpa_supplicant_connect(wpa_s, bss, ssid);
 
+	/*
+	 * Indicate that an explicitly requested roam 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 (radio_work_pending(wpa_s, "sme-connect")) {
+		wpa_s->roam_in_progress = 1;
+	}
+
 	return 0;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 }
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 5c40abd..01e4b4c 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1925,6 +1925,15 @@
 	wpa_s->reassociate = 1;
 	wpa_supplicant_connect(wpa_s, bss, ssid);
 
+	/*
+	 * Indicate that an explicitly requested roam 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 (radio_work_pending(wpa_s, "sme-connect")) {
+		wpa_s->roam_in_progress = 1;
+	}
+
 	return NULL;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 }
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index dd50201..7212c29 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -834,6 +834,8 @@
 	struct wpa_connect_work *cwork = work->ctx;
 	struct wpa_supplicant *wpa_s = work->wpa_s;
 
+	wpa_s->roam_in_progress = 0;
+
 	if (deinit) {
 		if (work->started)
 			wpa_s->connect_work = NULL;
@@ -872,6 +874,11 @@
 		return;
 	}
 
+	if (wpa_s->roam_in_progress) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"SME: Reject sme_authenticate() in favor of explicit roam request");
+		return;
+	}
 	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/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index e45efb0..2813880 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -526,6 +526,7 @@
 	u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this
 				     * field contains the target BSSID. */
 	int reassociate; /* reassociation requested */
+	int roam_in_progress; /* roam in progress */
 	unsigned int reassoc_same_bss:1; /* reassociating to the same BSS */
 	unsigned int reassoc_same_ess:1; /* reassociating to the same ESS */
 	int disconnected; /* all connections disabled; i.e., do no reassociate