* [PATCH] wifi: iwlwifi: mld: don't dereference link_sta->sta unchecked
@ 2026-10-29 4:40 Edwin Huish
0 siblings, 0 replies; only message in thread
From: Edwin Huish @ 2026-10-29 4:40 UTC (permalink / raw)
To: linux-wireless; +Cc: Miri Korenblit, Johannes Berg
mld->fw_id_to_link_sta[] can hold an entry whose ->sta is not set. The
driver already documents this in iwl_mld_rx_agg_session_expired():
/* sta should be valid unless the following happens:
* The firmware asserts which triggers a reconfig flow, but
* the reconfig fails before we set the pointer to sta into
* the fw_id_to_link_sta pointer table. mac80211 can't stop
* A-MPDU and hence the timer continues to run. Then, the
* timer expires and sta is NULL.
*/
Three other users of the table only check the link_sta pointer itself
and then go straight for ->sta:
iwl_mld_teardown_tdls_peers(), iwl_mld_tdls_sta_count(),
iwl_mld_mac80211_flush()
link_sta = wiphy_dereference(mld->wiphy, mld->fw_id_to_link_sta[i]);
if (IS_ERR_OR_NULL(link_sta))
continue;
if (!link_sta->sta->tdls) /* ->sta may be NULL */
iwl_mld_tdls_sta_count() was hit in the field on an Intel BE201
(8086:7740) running firmware bz-b0-fm-c0-c101 (101.6e695a70.0), in
exactly the situation described above: the firmware asserted twice
within a second (0x85 ADVANCED_SYSASSERT followed by 0x20100508) and
the restart failed with "FW error in SYNC CMD INIT_EXTENDED_CFG_CMD".
About a minute later wpa_supplicant re-associated and issued
NL80211_CMD_SET_STATION to update the power save parameters, which
ends up in iwl_mld_power_build_cmd() -> iwl_mld_tdls_sta_count():
BUG: kernel NULL pointer dereference, address: 0000000000000018
#PF: supervisor read access in kernel mode
Oops: 0000 [#1] SMP NOPTI
CPU: 7 PID: 1740 Comm: wpa_supplicant
RIP: 0010:iwl_mld_tdls_sta_count+0x48/0xd0 [iwlmld]
RAX: 000000000000000c RCX: ffff8c51a95ba0a8 RDX: 0000000000000000
Call Trace:
<TASK>
iwl_mld_power_build_cmd+0x11f/0x480 [iwlmld]
iwl_mld_update_mac_power+0x66/0xe0 [iwlmld]
iwl_mld_mac80211_vif_cfg_changed+0x58/0x120 [iwlmld]
ieee80211_vif_cfg_change_notify+0x10d/0x230 [mac80211]
ieee80211_recalc_ps_vif+0x41/0x60 [mac80211]
ieee80211_change_station+0x1e0/0x280 [mac80211]
nl80211_set_station+0x4e2/0x660 [cfg80211]
genl_family_rcv_msg_doit+0x120/0x190
note: wpa_supplicant[1740] exited with irqs disabled
The registers match the source: RAX is the loop index (12), RCX is mld,
and RDX - the result of loading link_sta->sta - is zero. The faulting
instruction reads sta->tdls at offset 0x18:
6d70: test %rdx,%rdx ; link_sta != NULL checked
6d73: je 6d8b
6d75: mov (%rdx),%rdx ; link_sta->sta, NOT checked
6d78: movzbl 0x18(%rdx),%edx ; sta->tdls <- faulting insn
Since the oops happened with interrupts disabled, the task died in
kernel mode without releasing the cfg80211/rtnl locks it held, which
then blocked gnome-shell on the leaked lock and froze the whole
desktop. The impact is therefore not limited to a dropped connection.
Handle the entries the same way agg.c already does, and skip them.
Tested on the affected machine: builds cleanly against 7.0.0-38-generic,
all three sites now test ->sta before loading sta->tdls, and WiFi still
associates and reconnects normally.
Signed-off-by: Edwin Huish <edwinhuish@gmail.com>
---
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -913,6 +913,11 @@ static void iwl_mld_teardown_tdls_peers(struct iwl_mld *mld)
if (IS_ERR_OR_NULL(link_sta))
continue;
+ if (!link_sta->sta) {
+ WARN_ON_ONCE(1);
+ continue;
+ }
+
if (!link_sta->sta->tdls)
continue;
@@ -1630,6 +1635,11 @@ int iwl_mld_tdls_sta_count(struct iwl_mld *mld)
if (IS_ERR_OR_NULL(link_sta))
continue;
+ if (!link_sta->sta) {
+ WARN_ON_ONCE(1);
+ continue;
+ }
+
if (!link_sta->sta->tdls)
continue;
@@ -1937,6 +1947,11 @@ static void iwl_mld_mac80211_flush(struct ieee80211_hw *hw,
if (IS_ERR_OR_NULL(link_sta))
continue;
+ if (!link_sta->sta) {
+ WARN_ON_ONCE(1);
+ continue;
+ }
+
/* Check that the sta belongs to the given vif */
if (vif && vif != iwl_mld_sta_from_mac80211(link_sta->sta)->vif)
continue;
--
2.43.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-29 4:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-29 4:40 [PATCH] wifi: iwlwifi: mld: don't dereference link_sta->sta unchecked Edwin Huish
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox