From: Alexandru Hossu Date: Fri, 15 May 2026 10:29:08 +0000 (+0200) Subject: wifi: mac80211: bounds-check link_id in ieee80211_ml_epcs X-Git-Tag: v7.0.11~52 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=863f1f02a3bd70dbd857b8ac4070292fde8cb4e2;p=thirdparty%2Fkernel%2Fstable.git wifi: mac80211: bounds-check link_id in ieee80211_ml_epcs [ Upstream commit f718506edd2d9c6a308ded9d13c632bf7b7d5a2c ] IEEE80211_MLE_STA_EPCS_CONTROL_LINK_ID is 0x000f, so link_id extracted from a PRIO_ACCESS ML element PER_STA_PROFILE subelement can be 0..15. sdata->link[] has IEEE80211_MLD_MAX_NUM_LINKS (15) entries (indices 0..14), making index 15 out-of-bounds. A connected WiFi 7 AP can trigger this by sending an EPCS Enable Response action frame with a PER_STA_PROFILE subelement where link_id = 15. The unsolicited-notification path (dialog_token = 0) is reachable any time EPCS is already enabled, without any prior client request. sdata->link[15] reads into the first word of sdata->activate_links_work (a wiphy_work whose embedded list_head is non-NULL after INIT_LIST_HEAD), so the NULL check on the result does not catch the invalid access. The garbage pointer is then passed to ieee80211_sta_wmm_params(), which dereferences link->sdata and crashes the kernel. The same class of bug was fixed for ieee80211_ml_reconfiguration() by commit 162d331d833d ("wifi: mac80211: bounds-check link_id in ieee80211_ml_reconfiguration"). Fixes: de86c5f60839 ("wifi: mac80211: Add support for EPCS configuration") Signed-off-by: Alexandru Hossu Link: https://patch.msgid.link/20260515102908.1653088-1-hossu.alexandru@gmail.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 991519ea4482..eba890366e9f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -11137,6 +11137,9 @@ static void ieee80211_ml_epcs(struct ieee80211_sub_if_data *sdata, control = get_unaligned_le16(pos); link_id = control & IEEE80211_MLE_STA_EPCS_CONTROL_LINK_ID; + if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) + continue; + link = sdata_dereference(sdata->link[link_id], sdata); if (!link) continue;