diff mbox series

[1/4] Use default IEs in wpa_supplicant_trigger_scan

Message ID 20230602221511.1237936-1-matthewmwang@chromium.org
State Accepted
Headers show
Series [1/4] Use default IEs in wpa_supplicant_trigger_scan | expand

Commit Message

Matthew Wang June 2, 2023, 10:15 p.m. UTC
wpa_supplicant_trigger_scan previously wouldn't include any of the IEs
generated by wpa_supplicant_extra_ies. Instruct it to do so in most
cases. This is necessary because MBO STAs are required to include MBO
capabilities in their probe requests.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
---
 doc/dbus.doxygen                        |  2 +-
 wpa_supplicant/bgscan_learn.c           |  2 +-
 wpa_supplicant/bgscan_simple.c          |  2 +-
 wpa_supplicant/dbus/dbus_new_handlers.c |  6 +++--
 wpa_supplicant/rrm.c                    |  2 +-
 wpa_supplicant/scan.c                   | 29 ++++++++++++++++++++++---
 wpa_supplicant/scan.h                   |  4 +++-
 wpa_supplicant/sme.c                    |  2 +-
 8 files changed, 38 insertions(+), 11 deletions(-)

Comments

Jouni Malinen Oct. 31, 2023, 10:04 a.m. UTC | #1
On Fri, Jun 02, 2023 at 03:15:08PM -0700, Matthew Wang wrote:
> wpa_supplicant_trigger_scan previously wouldn't include any of the IEs
> generated by wpa_supplicant_extra_ies. Instruct it to do so in most
> cases. This is necessary because MBO STAs are required to include MBO
> capabilities in their probe requests.

Thanks, all four patches applied with some cleanup and hwsim test case
changes to avoid breaking some memory allocation failure cases.
diff mbox series

Patch

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index 87f4c02fbbd..afea7f97add 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -209,7 +209,7 @@  fi.w1.wpa_supplicant1.CreateInterface.
 	      <tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th>
 	      <tr><td>Type</td><td>s</td><td>Type of the scan. Possible values: "active", "passive"</td><td>Yes</td>
 	      <tr><td>SSIDs</td><td>aay</td><td>Array of SSIDs to scan for (applies only if scan type is active)</td><td>No</td>
-	      <tr><td>IEs</td><td>aay</td><td>Information elements to used in active scan (applies only if scan type is active)</td><td>No</td>
+	      <tr><td>IEs</td><td>aay</td><td>Information elements to used in active scan (applies only if scan type is active). Default IEs will be used in absence of this option.</td><td>No</td>
 	      <tr><td>Channels</td><td>a(uu)</td><td>Array of frequencies to scan in form of (center, width) in MHz.</td><td>No</td>
 	      <tr><td>AllowRoam</td><td>b</td><td>TRUE (or absent) to allow a roaming decision based on the results of this scan, FALSE to prevent a roaming decision.</td><td>No</td>
 	    </table>
diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c
index 75bdec1c0a9..3db425963eb 100644
--- a/wpa_supplicant/bgscan_learn.c
+++ b/wpa_supplicant/bgscan_learn.c
@@ -305,7 +305,7 @@  static void bgscan_learn_timeout(void *eloop_ctx, void *timeout_ctx)
 	}
 
 	wpa_printf(MSG_DEBUG, "bgscan learn: Request a background scan");
-	if (wpa_supplicant_trigger_scan(wpa_s, &params)) {
+	if (wpa_supplicant_trigger_scan(wpa_s, &params, true)) {
 		wpa_printf(MSG_DEBUG, "bgscan learn: Failed to trigger scan");
 		eloop_register_timeout(data->scan_interval, 0,
 				       bgscan_learn_timeout, data, NULL);
diff --git a/wpa_supplicant/bgscan_simple.c b/wpa_supplicant/bgscan_simple.c
index 5a8f97c2a6a..1b12726d203 100644
--- a/wpa_supplicant/bgscan_simple.c
+++ b/wpa_supplicant/bgscan_simple.c
@@ -49,7 +49,7 @@  static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
 	 */
 
 	wpa_printf(MSG_DEBUG, "bgscan simple: Request a background scan");
-	if (wpa_supplicant_trigger_scan(wpa_s, &params)) {
+	if (wpa_supplicant_trigger_scan(wpa_s, &params, true)) {
 		wpa_printf(MSG_DEBUG, "bgscan simple: Failed to trigger scan");
 		eloop_register_timeout(data->scan_interval, 0,
 				       bgscan_simple_timeout, data, NULL);
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 67ce970d01b..d7fdea0ed90 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1630,6 +1630,7 @@  DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
 	struct wpa_driver_scan_params params;
 	size_t i;
 	dbus_bool_t allow_roam = 1;
+	bool custom_ies = false;
 
 	os_memset(&params, 0, sizeof(params));
 
@@ -1656,6 +1657,7 @@  DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
 			if (wpas_dbus_get_scan_ies(message, &variant_iter,
 						   &params, &reply) < 0)
 				goto out;
+			custom_ies = true;
 		} else if (os_strcmp(key, "Channels") == 0) {
 			if (wpas_dbus_get_scan_channels(message, &variant_iter,
 							&params, &reply) < 0)
@@ -1703,7 +1705,7 @@  DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
 			if (params.freqs && params.freqs[0]) {
 				wpa_s->last_scan_req = MANUAL_SCAN_REQ;
 				if (wpa_supplicant_trigger_scan(wpa_s,
-								&params)) {
+								&params, false)) {
 					reply = wpas_dbus_error_scan_error(
 						message,
 						"Scan request rejected");
@@ -1729,7 +1731,7 @@  DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
 		}
 
 		wpa_s->last_scan_req = MANUAL_SCAN_REQ;
-		if (wpa_supplicant_trigger_scan(wpa_s, &params)) {
+		if (wpa_supplicant_trigger_scan(wpa_s, &params, !custom_ies)) {
 			reply = wpas_dbus_error_scan_error(
 				message, "Scan request rejected");
 		}
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index 238fe68da05..bf6575a0bf3 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -1033,7 +1033,7 @@  static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 	}
 	os_get_reltime(&wpa_s->beacon_rep_scan);
 	if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
-	    wpa_supplicant_trigger_scan(wpa_s, params))
+	    wpa_supplicant_trigger_scan(wpa_s, params, true))
 		wpas_rrm_refuse_request(wpa_s);
 	params->duration = prev_duration;
 }
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index f45d88a754e..1803d4b578e 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -278,19 +278,42 @@  static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
  * wpa_supplicant_trigger_scan - Request driver to start a scan
  * @wpa_s: Pointer to wpa_supplicant data
  * @params: Scan parameters
+ * @default_ies: Whether or not to use the default IEs in the probe request.
+ * Note that this will free any existing IEs set in @params, so this shouldn't
+ * be set if the IEs have already been set with wpa_supplicant_extra_ies.
+ * Otherwise, wpabuf_free will lead to a double-free.
  * Returns: 0 on success, -1 on failure
  */
 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
-				struct wpa_driver_scan_params *params)
+				struct wpa_driver_scan_params *params,
+				bool default_ies)
 {
 	struct wpa_driver_scan_params *ctx;
+	struct wpabuf *ies = NULL;
 
 	if (wpa_s->scan_work) {
 		wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
 		return -1;
 	}
 
+	if (default_ies) {
+		if (params->extra_ies_len) {
+			os_free((u8 *) params->extra_ies);
+			params->extra_ies = NULL;
+			params->extra_ies_len = 0;
+		}
+		ies = wpa_supplicant_extra_ies(wpa_s);
+		if (ies) {
+			params->extra_ies = wpabuf_head(ies);
+			params->extra_ies_len = wpabuf_len(ies);
+		}
+	}
 	ctx = wpa_scan_clone_params(params);
+	if (ies) {
+		wpabuf_free(ies);
+		params->extra_ies = NULL;
+		params->extra_ies_len = 0;
+	}
 	if (!ctx ||
 	    radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
 	{
@@ -674,7 +697,7 @@  void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
 }
 
 
-static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
+struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 {
 	struct wpabuf *extra_ie = NULL;
 	u8 ext_capab[18];
@@ -1474,7 +1497,7 @@  scan:
 		wpas_p2p_scan_freqs(wpa_s, &params, true);
 #endif /* CONFIG_P2P */
 
-	ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
+	ret = wpa_supplicant_trigger_scan(wpa_s, scan_params, false);
 
 	if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
 	    !wpa_s->manual_scan_freqs) {
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 30f43951c2a..17c7b06a6bd 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -45,7 +45,8 @@  void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
 				    int scanning);
 struct wpa_driver_scan_params;
 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
-				struct wpa_driver_scan_params *params);
+				struct wpa_driver_scan_params *params,
+				bool default_ies);
 struct wpa_scan_results *
 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
 				struct scan_info *info, int new_scan);
@@ -94,5 +95,6 @@  int wpa_add_scan_freqs_list(struct wpa_supplicant *wpa_s,
 			    struct wpa_driver_scan_params *params,
 			    bool is_6ghz, bool only_6ghz_psc,
 			    bool exclude_radar);
+struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s);
 
 #endif /* SCAN_H */
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 4ed0a3003ff..8e72643f1dc 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -3083,7 +3083,7 @@  static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 	params.low_priority = 1;
 	wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
 
-	if (wpa_supplicant_trigger_scan(wpa_s, &params))
+	if (wpa_supplicant_trigger_scan(wpa_s, &params, true))
 		wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
 	else
 		wpa_s->sme.sched_obss_scan = 1;