include $(TOPDIR)/rules.mk
PKG_NAME:=hostapd
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE_URL:=https://w1.fi/hostap.git
PKG_SOURCE_PROTO:=git
--- /dev/null
+From 46dd5a4ffc9bcf44cf8fc45120b3e1e5ec922187 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Tue, 31 Mar 2026 23:24:04 +0300
+Subject: AP MLD: Fix link ID validation in Basic MLE parsing
+
+Link ID 15 can be indicated in the field, but that is not a valid value
+and must be rejected to avoid issues pointing beyond the array of links
+for a non-AP MLD. Without this, an invalid MLE could result in writing
+beyond the end of the buffer and causing process termination or
+unexpected behavior.
+
+Fixes: 5f5db9366cde ("AP: MLO: Process Multi-Link element from (Re)Association Request frame")
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ src/ap/ieee802_11_eht.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/src/ap/ieee802_11_eht.c
++++ b/src/ap/ieee802_11_eht.c
+@@ -1382,6 +1382,7 @@ u16 hostapd_process_ml_assoc_req(struct
+ u16 control;
+ const u8 *sub_elem_end;
+ int num_frag_subelems;
++ u8 link_id;
+
+ num_frag_subelems =
+ ieee802_11_defrag_mle_subelem(mlbuf, pos,
+@@ -1433,8 +1434,13 @@ u16 hostapd_process_ml_assoc_req(struct
+ goto out;
+ }
+ control = WPA_GET_LE16(pos);
+- link_info = &info->links[control &
+- BASIC_MLE_STA_CTRL_LINK_ID_MASK];
++ link_id = control & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
++ if (link_id >= MAX_NUM_MLD_LINKS) {
++ wpa_printf(MSG_DEBUG,
++ "MLD: Invalid Link ID in Per-STA Profile subelement");
++ goto out;
++ }
++ link_info = &info->links[link_id];
+ pos += 2;
+
+ if (!(control & BASIC_MLE_STA_CTRL_COMPLETE_PROFILE)) {
--- /dev/null
+From aa9d345887389a251c63a3781d2ad2940d079193 Mon Sep 17 00:00:00 2001
+From: Amarnath Hullur Subramanyam <amarnathhs@google.com>
+Date: Thu, 30 Apr 2026 18:24:35 -0700
+Subject: BSS: Add bounds check for link_id in Basic MLE parsing
+
+In wpa_bss_parse_basic_ml_element() in bss.c, an extracted link_id is
+used without validation against the maximum allowed links
+(MAX_NUM_MLD_LINKS). Processing a malformed Basic Multi-Link element
+(MLE) with an out-of-bounds link_id could lead to memory corruption.
+However, the modified location is within the body of the received frame
+and as such, this does not result in additional issues since that area
+is controlled by the transmitter of the frame. In any case, it is better
+to be explicit with validating the Link ID value.
+
+This commit introduces a strict bounds check immediately after link_id
+extraction. If link_id exceeds or equals MAX_NUM_MLD_LINKS, parsing is
+gracefully aborted with a debug log entry.
+
+Fixes: de5e01010cb2 ("wpa_supplicant: Support ML probe request")
+Signed-off-by: Amarnath Hullur Subramanyam <amarnathhs@google.com>
+---
+ wpa_supplicant/bss.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/wpa_supplicant/bss.c
++++ b/wpa_supplicant/bss.c
+@@ -2055,6 +2055,11 @@ void wpa_bss_parse_basic_ml_element(stru
+ goto out;
+
+ link_id = ml_basic_common_info->variable[0] & EHT_ML_LINK_ID_MSK;
++ if (link_id >= MAX_NUM_MLD_LINKS) {
++ wpa_printf(MSG_DEBUG, "MLD: Invalid link ID %u in Basic MLE",
++ link_id);
++ goto out;
++ }
+
+ os_memcpy(bss->mld_addr, ml_basic_common_info->mld_addr, ETH_ALEN);
+
--- /dev/null
+From a8531e3d871e6fa72f2f85d91e9f787326b2af8b Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Tue, 31 Mar 2026 23:16:08 +0300
+Subject: MLD: Validate MLE Link ID fields in association rejection case
+
+The Link ID Info field in the Common Info field needs to ignore the
+reserved bits to be more extensible for future. Both that link ID for
+the association link and the link IDs for other links need to be
+verified to be within the valid range (0-14), so check that here. The
+parsed link ID was not used for anything yet, but it is better to make
+sure this in theory common parser is not exposing invalid data to the
+caller should it be used for additional purposes in the future.
+
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ wpa_supplicant/events.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -4318,7 +4318,12 @@ static unsigned int wpas_ml_parse_assoc(
+ pos = common_info->variable;
+
+ /* Store the information for the association link */
+- ml_info[i].link_id = *pos;
++ ml_info[i].link_id = *pos & EHT_ML_LINK_ID_MSK;
++ if (ml_info[i].link_id >= MAX_NUM_MLD_LINKS) {
++ wpa_printf(MSG_DEBUG,
++ "MLD: Invalid Link ID value for assoc link");
++ goto out;
++ }
+ pos++;
+
+ /* Skip the BSS Parameters Change Count */
+@@ -4474,6 +4479,10 @@ static unsigned int wpas_ml_parse_assoc(
+ MAC2STR(pos + 1), nstr_bitmap_len);
+
+ ml_info[i].link_id = ctrl & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
++ if (ml_info[i].link_id >= MAX_NUM_MLD_LINKS) {
++ wpa_printf(MSG_DEBUG, "MLD: Invalid Link ID value");
++ goto out;
++ }
+ os_memcpy(ml_info[i].bssid, pos + 1, ETH_ALEN);
+
+ pos += sta_info_len;
--- /dev/null
+From 56216d113909650ae59621dc2dd16157afb94948 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Mon, 18 May 2026 11:57:02 +0300
+Subject: Verify MLD link ID validity in get_basic_mle_link_id()
+
+Link ID is 0..14, so ignore value 15 if an invalid frame is processed.
+It does not look like the returned value was actually used to reference
+any local array, but in any case, it is better to not return an invalid
+value to reduce risk for unexpected behavior in the future.
+
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ src/common/ieee802_11_common.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/src/common/ieee802_11_common.c
++++ b/src/common/ieee802_11_common.c
+@@ -3714,6 +3714,7 @@ int get_basic_mle_link_id(const u8 *buf,
+ ETH_ALEN; /* MLD MAC Address field (Basic) */
+ size_t common_info_limit;
+ u8 common_info_len;
++ u8 link_id;
+
+ if (len < MULTI_LINK_CONTROL_LEN)
+ return -1;
+@@ -3735,7 +3736,11 @@ int get_basic_mle_link_id(const u8 *buf,
+ if (link_id_pos + EHT_ML_LINK_ID_LEN > common_info_limit)
+ return -1;
+
+- return buf[link_id_pos] & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
++ link_id = buf[link_id_pos] & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
++ if (link_id >= MAX_NUM_MLD_LINKS)
++ return -1;
++
++ return link_id;
+ }
+
+
--- /dev/null
+From e4bd3442c2223802bf8c4a4d868e3b9443c7caf4 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Mon, 18 May 2026 12:13:21 +0300
+Subject: MLD: Verify link ID validity in MLE in reconfiguration cases
+
+Ignore or reject invalid link ID value 15 in ML reconfiguration.
+
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ src/ap/ieee802_11_eht.c | 2 ++
+ wpa_supplicant/bss.c | 3 ++-
+ wpa_supplicant/wnm_sta.c | 3 ++-
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/src/ap/ieee802_11_eht.c
++++ b/src/ap/ieee802_11_eht.c
+@@ -2166,6 +2166,8 @@ hostapd_parse_link_reconf_req_sta_profil
+
+ link_id = sta_control & EHT_PER_STA_RECONF_CTRL_LINK_ID_MSK;
+ wpa_printf(MSG_DEBUG, "MLD: Per-STA profile for link=%u", link_id);
++ if (link_id >= MAX_NUM_MLD_LINKS)
++ goto out;
+
+ reconf_type_mask =
+ sta_control & EHT_PER_STA_RECONF_CTRL_OP_UPDATE_TYPE_MSK;
+--- a/wpa_supplicant/bss.c
++++ b/wpa_supplicant/bss.c
+@@ -2243,7 +2243,8 @@ u16 wpa_bss_parse_reconf_ml_element(stru
+ u8 link_id;
+
+ link_id = control & EHT_PER_STA_RECONF_CTRL_LINK_ID_MSK;
+- removed_links |= BIT(link_id);
++ if (link_id < MAX_NUM_MLD_LINKS)
++ removed_links |= BIT(link_id);
+ }
+
+ pos += 2 + sub_elem_len;
+--- a/wpa_supplicant/wnm_sta.c
++++ b/wpa_supplicant/wnm_sta.c
+@@ -546,7 +546,8 @@ static void wnm_parse_neighbor_report_mu
+ control = le_to_host16(sta_prof->sta_control);
+
+ link_id = control & EHT_PER_STA_RECONF_CTRL_LINK_ID_MSK;
+- rep->mld_links |= BIT(link_id);
++ if (link_id < MAX_NUM_MLD_LINKS)
++ rep->mld_links |= BIT(link_id);
+ }
+
+ pos += 2 + sub_elem_len;
--- /dev/null
+From ce1a8612e309fe86133ecf05ffb452b0bdf3b035 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Mon, 18 May 2026 15:45:15 +0300
+Subject: AP MLD: Verify AP MLD link ID validity before updating bitmap of
+ links
+
+Link ID is 0..14, so ignore value 15 if an invalid frame is processed.
+It does not look like the invalid value was actually used to reference
+any local array, but in any case, it is better to not mark an invalid
+link as being specified.
+
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ src/ap/beacon.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/src/ap/beacon.c
++++ b/src/ap/beacon.c
+@@ -1411,6 +1411,7 @@ static bool parse_ml_probe_req(const str
+ for_each_element_id(sub, 0, pos, len) {
+ const struct ieee80211_eht_per_sta_profile *sta;
+ u16 sta_control;
++ u8 link_id;
+
+ if (*links == 0xffff)
+ *links = 0;
+@@ -1430,7 +1431,9 @@ static bool parse_ml_probe_req(const str
+ * partial profile was requested.
+ */
+ sta_control = le_to_host16(sta->sta_control);
+- *links |= BIT(sta_control & BASIC_MLE_STA_CTRL_LINK_ID_MASK);
++ link_id = sta_control & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
++ if (link_id < MAX_NUM_MLD_LINKS)
++ *links |= BIT(link_id);
+ }
+
+ if (!for_each_element_completed(sub, pos, len)) {
--- /dev/null
+From 41c86a2ebed50567c73de23c102c2bf83eb883f2 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Tue, 31 Mar 2026 17:47:03 +0300
+Subject: MLD: Fix length check in common info for association failure cases
+
+It is not sufficient to check that the indicated common info length is
+sufficiently large to contain the information; there needs to be a check
+for the indicated value to not be too large to go beyond the end of the
+MLE as well. Without this, invalid MLE might result in ml_len wrapping
+around to a huge value and reading beyond the end of the buffer for the
+received frame. This could result in process termination.
+
+Add the missed check for the Common Info field not being truncated in
+the MLE in association failure cases.
+
+Fixes: a58a0c592e20 ("MLD: Fix Multi-Link element parsing for association failures")
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ wpa_supplicant/events.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -4306,6 +4306,13 @@ static unsigned int wpas_ml_parse_assoc(
+ goto out;
+ }
+
++ if (sizeof(*ml) + common_info->len > ml_len) {
++ wpa_printf(MSG_DEBUG,
++ "MLD: Truncated common info (common_info->len=%u ml_len=%zu)",
++ common_info->len, ml_len);
++ goto out;
++ }
++
+ wpa_printf(MSG_DEBUG, "MLD: address: " MACSTR,
+ MAC2STR(common_info->mld_addr));
+
--- /dev/null
+From 595194d0305189922a057e8ea8b743a1bd8d2d29 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+Date: Mon, 18 May 2026 16:17:15 +0300
+Subject: BSS: Fix validation of ML common info length during scan result
+ parsing
+
+The validation of the ML common info length before use allowed reading
+beyond the end of the element when the MSD info and EML capabilities
+were claimed to be present but were not actually inclued. While this was
+noticed after reading these fields and further processing of the element
+was stopped, this could result in reading two bytes beyond the end of
+the buffer.
+
+Avoid this by checking the remaining length explicitly for the optiional
+fields.
+
+Fixes: 1b07e8baca13 ("BSS: Use correct AP MLD ID")
+Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
+---
+ wpa_supplicant/bss.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/wpa_supplicant/bss.c
++++ b/wpa_supplicant/bss.c
+@@ -2006,13 +2006,20 @@ void wpa_bss_parse_basic_ml_element(stru
+
+ /* Medium Synchronization Delay Information */
+ if (le_to_host16(eht_ml->ml_control) &
+- BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO)
++ BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) {
++ if (ml_basic_common_info->len <
++ sizeof(*ml_basic_common_info) + pos + 2)
++ goto out;
+ pos += 2;
++ }
+
+ /* EML Capabilities */
+ bss->eml_capa = 0;
+ if (le_to_host16(eht_ml->ml_control) &
+ BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) {
++ if (ml_basic_common_info->len <
++ sizeof(*ml_basic_common_info) + pos + 2)
++ goto out;
+ bss->eml_capa =
+ WPA_GET_LE16(&ml_basic_common_info->variable[pos]);
+ pos += 2;
+@@ -2020,6 +2027,8 @@ void wpa_bss_parse_basic_ml_element(stru
+
+ /* MLD Capabilities And Operations (always present, see
+ * control/control_mask) */
++ if (ml_basic_common_info->len < sizeof(*ml_basic_common_info) + pos + 2)
++ goto out;
+ bss->mld_capa = WPA_GET_LE16(&ml_basic_common_info->variable[pos]);
+ pos += 2;
+
os_memset(&eapol_test, 0, sizeof(eapol_test));
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
-@@ -6627,8 +6627,8 @@ static int wpas_pasn_auth(struct wpa_sup
+@@ -6643,8 +6643,8 @@ static int wpas_pasn_auth(struct wpa_sup
#endif /* CONFIG_PASN */
{
struct wpa_supplicant *wpa_s = ctx;
int resched;
-@@ -7622,7 +7622,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -7638,7 +7638,7 @@ void wpa_supplicant_event(void *ctx, enu
}
}
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
-@@ -1464,6 +1464,12 @@ void handle_probe_req(struct hostapd_dat
+@@ -1467,6 +1467,12 @@ void handle_probe_req(struct hostapd_dat
int mld_id;
u16 links;
#endif /* CONFIG_IEEE80211BE */
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
ssi_signal < hapd->iconf->rssi_ignore_probe_request)
-@@ -1671,6 +1677,12 @@ void handle_probe_req(struct hostapd_dat
+@@ -1674,6 +1680,12 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
MULTI_AP_FRONTHAUL_BSS);
wpa_s->multi_ap_ie = 1;
}
-@@ -5857,6 +5864,13 @@ static void wpas_event_rx_mgmt_action(st
+@@ -5873,6 +5880,13 @@ static void wpas_event_rx_mgmt_action(st
}
#endif /* CONFIG_WNM */
#ifdef CONFIG_GAS
if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
-@@ -6663,6 +6677,7 @@ void supplicant_event(void *ctx, enum wp
+@@ -6679,6 +6693,7 @@ void supplicant_event(void *ctx, enum wp
event_to_string(event), event);
#endif /* CONFIG_NO_STDOUT_DEBUG */
* ' ' (ascii 32): all environments
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
-@@ -1701,7 +1701,7 @@ void handle_probe_req(struct hostapd_dat
+@@ -1704,7 +1704,7 @@ void handle_probe_req(struct hostapd_dat
if (hapd->conf->no_probe_resp_if_max_sta &&
is_multicast_ether_addr(mgmt->da) &&
is_multicast_ether_addr(mgmt->bssid) &&
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
-@@ -1523,7 +1523,7 @@ void handle_probe_req(struct hostapd_dat
+@@ -1526,7 +1526,7 @@ void handle_probe_req(struct hostapd_dat
* is less likely to see them (Probe Request frame sent on a
* neighboring, but partially overlapping, channel).
*/