nl80211: add extra-ies only if allowed by driver (continued)

Gregor Feierabend gf.lst at pm.me
Thu May 22 14:34:02 PDT 2025


Ah, thanks. I missed that. I have attached a patch doing exactly the
changes performed in these two commits in case anybody needs to fix
the current version on their machine.

On Tue, May 20, 2025 at 12:42:52PM +0200, Nicolas Cavallari wrote:
> On 19/05/2025 16:54, Gregor Feierabend wrote:
> > Hi!
> >
> > The issue of wpa_supplicant-2.10 breaking broadcom-wl based adapters as
> > reported by Étienne Morice/David Bauer on 30 Jan 2022 persists in wpa_supplicant-2.11 (see: https://lists.infradead.org/pipermail/hostap/2022-January/040185.html).
> >
> > Was it an oversight to not include the suggested changes in version 2.11?
> >
> > Below is the earlier proposed patch, adjusted to wpa_supplicant-2.11.
> 
> A different patch is currently in the git repository:
> 
> commit 2fe7a2b80e9ebb7ed550d82e4d4661104b489791
> Author: Jouni Malinen <j at w1.fi>
> Date:   Fri Dec 27 22:36:29 2024 +0200
> 
> Do not add extra IEs to scan request if they do not fit driver limit
> 
> For now, each separate IE is being checked on its own, so this is not a
> complete check on the total length, but a useful step in avoiding some
> known issues with drivers that do not support any IEs being added. A
> more complete validation would need rules on determining which IE is of
> higher priority than the other ones, but that might not be needed unless
> there are drivers that have nonzero, but still quite small, limit on
> extra IEs.
> 
> Signed-off-by: Jouni Malinen <j at w1.fi>
> 
> commit 66442d1bcbf2c06c29b55ff8930dbe7d46b60e98
> Author: Jouni Malinen <j at w1.fi>
> Date:   Fri Dec 27 20:43:42 2024 +0200
> 
> nl80211: Fetch maximum length of extra IE(s) for Probe Request frames
> 
> This can be helpful in determining which IE(s) to add to Probe Request
> frames in scan commands based on driver capabilities.
> 
> Signed-off-by: Jouni Malinen <j at w1.fi>
> 
> 
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap
-------------- next part --------------
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 3e77474..4c2803e 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2450,6 +2450,10 @@ struct wpa_driver_capa {
 	unsigned int mbssid_max_interfaces;
 	/* Maximum profile periodicity for enhanced MBSSID advertisement */
 	unsigned int ema_max_periodicity;
+
+	/* Maximum number of bytes of extra IE(s) that can be added to Probe
+	 * Request frames */
+	size_t max_probe_req_ie_len;
 };
 
 
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index e6fbad9..f8f2949 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -11124,7 +11124,8 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
 				  "capa.max_sched_scan_plan_interval=%u\n"
 				  "capa.max_sched_scan_plan_iterations=%u\n"
 				  "capa.mbssid_max_interfaces=%u\n"
-				  "capa.ema_max_periodicity=%u\n",
+				  "capa.ema_max_periodicity=%u\n"
+				  "capa.max_probe_req_ie_len=%zu\n",
 				  drv->capa.key_mgmt,
 				  drv->capa.enc,
 				  drv->capa.auth,
@@ -11149,7 +11150,8 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
 				  drv->capa.max_sched_scan_plan_interval,
 				  drv->capa.max_sched_scan_plan_iterations,
 				  drv->capa.mbssid_max_interfaces,
-				  drv->capa.ema_max_periodicity);
+				  drv->capa.ema_max_periodicity,
+				  drv->capa.max_probe_req_ie_len);
 		if (os_snprintf_error(end - pos, res))
 			return pos - buf;
 		pos += res;
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index dc16bd4..9ce6334 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -959,6 +959,10 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
 		capa->max_scan_ssids =
 			nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
 
+	if (tb[NL80211_ATTR_MAX_SCAN_IE_LEN])
+		capa->max_probe_req_ie_len =
+			nla_get_u16(tb[NL80211_ATTR_MAX_SCAN_IE_LEN]);
+
 	if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
 		capa->max_sched_scan_ssids =
 			nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
@@ -1196,6 +1200,10 @@ static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
 	info->capa = &drv->capa;
 	info->drv = drv;
 
+	/* Default to large buffer of extra IE(s) to maintain previous behavior
+	 * if the driver does not support reporting an accurate limit. */
+	info->capa->max_probe_req_ie_len = 1500;
+
 	feat = get_nl80211_protocol_features(drv);
 	if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
 		flags = NLM_F_DUMP;
diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index b055e68..184df49 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -224,6 +224,11 @@ nl80211_scan_common(struct i802_bss *bss, u8 cmd,
 	if (params->extra_ies) {
 		wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
 			    params->extra_ies, params->extra_ies_len);
+		if (params->extra_ies_len > drv->capa.max_probe_req_ie_len)
+			wpa_printf(MSG_INFO,
+				   "nl80211: Extra IEs for scan do not fit driver limit (%zu > %zu) - this is likely to fail",
+				   params->extra_ies_len,
+				   drv->capa.max_probe_req_ie_len);
 		if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
 			    params->extra_ies))
 			goto fail;
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index 59b15da..117b30c 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -460,6 +460,10 @@ void wpas_mbo_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ie)
 {
 	u8 *len;
 
+	if (wpa_s->drv_max_probe_req_ie_len <
+	    9 + ((wpa_s->enable_oce & OCE_STA) ? 3 : 0))
+		return;
+
 	wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
 	len = wpabuf_put(ie, 1);
 
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 85c1ea8..29b18e0 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -602,7 +602,8 @@ void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s,
 	/* EID + 0-length (wildcard) mesh-id */
 	size_t ielen = 2;
 
-	if (wpabuf_resize(extra_ie, ielen) == 0) {
+	if (ielen <= wpa_s->drv_max_probe_req_ie_len &&
+	    wpabuf_resize(extra_ie, ielen) == 0) {
 		wpabuf_put_u8(*extra_ie, WLAN_EID_MESH_ID);
 		wpabuf_put_u8(*extra_ie, 0);
 	}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 8b59e40..a600502 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -750,17 +750,20 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
 					     sizeof(ext_capab), NULL);
 	if (ext_capab_len > 0 &&
+	    (size_t) ext_capab_len < wpa_s->drv_max_probe_req_ie_len &&
 	    wpabuf_resize(&extra_ie, ext_capab_len) == 0)
 		wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
 
 #ifdef CONFIG_INTERWORKING
 	if (wpa_s->conf->interworking &&
+	    wpa_s->drv_max_probe_req_ie_len >= 2 &&
 	    wpabuf_resize(&extra_ie, 100) == 0)
 		wpas_add_interworking_elements(wpa_s, extra_ie);
 #endif /* CONFIG_INTERWORKING */
 
 #ifdef CONFIG_MBO
-	if (wpa_s->enable_oce & OCE_STA)
+	if ((wpa_s->enable_oce & OCE_STA) &&
+	    wpa_s->drv_max_probe_req_ie_len >= 5)
 		wpas_fils_req_param_add_max_channel(wpa_s, &extra_ie);
 #endif /* CONFIG_MBO */
 
@@ -774,17 +777,19 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 						&wpa_s->wps->dev,
 						wpa_s->wps->uuid, req_type,
 						0, NULL);
-		if (wps_ie) {
-			if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
-				wpabuf_put_buf(extra_ie, wps_ie);
-			wpabuf_free(wps_ie);
-		}
+		if (wps_ie &&
+		    wpabuf_len(wps_ie) <= wpa_s->drv_max_probe_req_ie_len &&
+		    wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
+			wpabuf_put_buf(extra_ie, wps_ie);
+		wpabuf_free(wps_ie);
 	}
 
 #ifdef CONFIG_P2P
 	if (wps) {
 		size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
-		if (wpabuf_resize(&extra_ie, ielen) == 0)
+
+		if (ielen <= wpa_s->drv_max_probe_req_ie_len &&
+		    wpabuf_resize(&extra_ie, ielen) == 0)
 			wpas_p2p_scan_ie(wpa_s, extra_ie);
 	}
 #endif /* CONFIG_P2P */
@@ -794,12 +799,14 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 #endif /* CONFIG_WPS */
 
 #ifdef CONFIG_HS20
-	if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 9) == 0)
+	if (wpa_s->conf->hs20 && wpa_s->drv_max_probe_req_ie_len >= 9 &&
+	    wpabuf_resize(&extra_ie, 9) == 0)
 		wpas_hs20_add_indication(extra_ie, -1, 0);
 #endif /* CONFIG_HS20 */
 
 #ifdef CONFIG_FST
 	if (wpa_s->fst_ies &&
+	    wpa_s->drv_max_probe_req_ie_len >= wpabuf_len(wpa_s->fst_ies) &&
 	    wpabuf_resize(&extra_ie, wpabuf_len(wpa_s->fst_ies)) == 0)
 		wpabuf_put_buf(extra_ie, wpa_s->fst_ies);
 #endif /* CONFIG_FST */
@@ -813,7 +820,8 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 	if (wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ]) {
 		struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ];
 
-		if (wpabuf_resize(&extra_ie, wpabuf_len(buf)) == 0)
+		if (wpa_s->drv_max_probe_req_ie_len >= wpabuf_len(buf) &&
+		    wpabuf_resize(&extra_ie, wpabuf_len(buf)) == 0)
 			wpabuf_put_buf(extra_ie, buf);
 	}
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 037bfa3..940042f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7393,12 +7393,15 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		    capa.mac_addr_rand_sched_scan_supported)
 			wpa_s->mac_addr_rand_supported |=
 				(MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
+		wpa_s->drv_max_probe_req_ie_len = capa.max_probe_req_ie_len;
 
 		wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
 		if (wpa_s->extended_capa &&
 		    wpa_s->extended_capa_len >= 3 &&
 		    wpa_s->extended_capa[2] & 0x40)
 			wpa_s->multi_bss_support = 1;
+	} else {
+		wpa_s->drv_max_probe_req_ie_len = 1500;
 	}
 #ifdef CONFIG_PASN
 	wpa_pasn_sm_set_caps(wpa_s->wpa, wpa_s->drv_flags2);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 110a864..8b7993f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -922,6 +922,7 @@ struct wpa_supplicant {
 	unsigned int drv_enc;
 	unsigned int drv_rrm_flags;
 	unsigned int drv_max_acl_mac_addrs;
+	size_t drv_max_probe_req_ie_len;
 
 	/*
 	 * A bitmap of supported protocols for probe response offload. See
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 249 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/hostap/attachments/20250522/eb83bbb0/attachment.sig>


More information about the Hostap mailing list