From 17bdf34c49687baa7c3166d4fcb2f50563b63c4f Mon Sep 17 00:00:00 2001 From: Matthew Wang Date: Fri, 2 Jun 2023 15:15:08 -0700 Subject: [PATCH] Use default IEs in wpa_supplicant_trigger_scan() 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 Request frames. Signed-off-by: Matthew Wang --- doc/dbus.doxygen | 2 +- wpa_supplicant/bgscan_learn.c | 2 +- wpa_supplicant/bgscan_simple.c | 2 +- wpa_supplicant/dbus/dbus_new_handlers.c | 7 ++++-- wpa_supplicant/rrm.c | 2 +- wpa_supplicant/scan.c | 30 +++++++++++++++++++++++-- wpa_supplicant/scan.h | 3 ++- wpa_supplicant/sme.c | 2 +- 8 files changed, 40 insertions(+), 10 deletions(-) diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen index 409db9522..17d4df06a 100644 --- a/doc/dbus.doxygen +++ b/doc/dbus.doxygen @@ -209,7 +209,7 @@ fi.w1.wpa_supplicant1.CreateInterface. KeyValue typeDescriptionRequired TypesType of the scan. Possible values: "active", "passive"Yes SSIDsaayArray of SSIDs to scan for (applies only if scan type is active)No - IEsaayInformation elements to used in active scan (applies only if scan type is active)No + IEsaayInformation elements to used in active scan (applies only if scan type is active). Default IEs will be used in absence of this option.No Channelsa(uu)Array of frequencies to scan in form of (center, width) in MHz.No AllowRoambTRUE (or absent) to allow a roaming decision based on the results of this scan, FALSE to prevent a roaming decision.No NonColoc6GHzbTRUE to force scanning of non-PSC 6 GHz channels, FALSE (or absent) to skip scanning of non-PSC 6 GHz channels.No diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c index 75bdec1c0..3db425963 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, ¶ms)) { + if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, 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 5a8f97c2a..1b12726d2 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, ¶ms)) { + if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, 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 b47f130ae..665126711 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -1632,6 +1632,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, dbus_bool_t allow_roam = TRUE; dbus_bool_t non_coloc_6ghz = FALSE; dbus_bool_t scan_6ghz_only = FALSE; + bool custom_ies = false; os_memset(¶ms, 0, sizeof(params)); @@ -1658,6 +1659,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, if (wpas_dbus_get_scan_ies(message, &variant_iter, ¶ms, &reply) < 0) goto out; + custom_ies = true; } else if (os_strcmp(key, "Channels") == 0) { if (wpas_dbus_get_scan_channels(message, &variant_iter, ¶ms, &reply) < 0) @@ -1724,7 +1726,8 @@ 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, - ¶ms)) { + ¶ms, + false)) { reply = wpas_dbus_error_scan_error( message, "Scan request rejected"); @@ -1750,7 +1753,7 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, } wpa_s->last_scan_req = MANUAL_SCAN_REQ; - if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) { + if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, !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 238fe68da..bf6575a0b 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 e4883d518..e4b72a8fa 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -24,6 +24,8 @@ #include "scan.h" #include "mesh.h" +static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s); + static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) { @@ -278,19 +280,43 @@ 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 + * frames. 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) { @@ -1534,7 +1560,7 @@ scan: wpas_p2p_scan_freqs(wpa_s, ¶ms, 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 30f43951c..4a21b4221 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); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index ab64d467b..9f12a7b3c 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -3093,7 +3093,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, ¶ms)) + if (wpa_supplicant_trigger_scan(wpa_s, ¶ms, true)) wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan"); else wpa_s->sme.sched_obss_scan = 1;