* [PATCH] wifi: mac80211: drain link readers before stopping removed links
@ 2026-10-28 14:17 Zhao Li
0 siblings, 0 replies; only message in thread
From: Zhao Li @ 2026-10-28 14:17 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, linux-kernel, stable
Removing an MLO link can leave work queued on its link container after
the container is freed.
ieee80211_tear_down_links() stops each link before the RCU grace period.
A reader that fetched the link earlier can therefore queue work after
ieee80211_link_stop() has canceled it. ieee80211_request_smps() and
ieee80211_csa_finish() can both reach this window.
Record each removed link while removing its keys and debugfs state. Wait
for RCU readers, then stop the recorded links so cancellation includes
work queued by those readers. Free the detached keys after the grace
period as before.
LLM assistance was used to find the bug and review.
Fixes: efe9c2bfd1a8 ("wifi: mac80211: isolate driver from inactive links")
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
---
Validation: A W=1 module build with MODPOST passed. In a QEMU KASAN
guest on the declared base, a built-in test reader held link 1 under RCU
while ieee80211_vif_set_links() removed it. Each of three boots reported
22 unique use-after-free reports before the change and none after it,
with no lockdep report. A reproducer is available on request.
Sparse C=2 passed. Targeted Smatch introduced no new diagnostics.
If "wifi: mac80211: free keys asynchronously" lands first, the key-list
context will need refreshing; the RCU wait remains necessary for link
readers:
https://lore.kernel.org/r/20261026125145.68153c510dfe.Ieaf95b8e1336f07866f54d174f699c6aa079d9b8@changeid
net/mac80211/link.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 931950a10508..41c7dfc49a24 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -191,6 +191,7 @@ struct link_container {
static void ieee80211_tear_down_links(struct ieee80211_sub_if_data *sdata,
struct link_container **links, u16 mask)
{
+ struct ieee80211_link_data *stop[IEEE80211_MLD_MAX_NUM_LINKS] = {};
struct ieee80211_link_data *link;
LIST_HEAD(keys);
unsigned int link_id;
@@ -205,11 +206,16 @@ static void ieee80211_tear_down_links(struct ieee80211_sub_if_data *sdata,
continue;
ieee80211_remove_link_keys(link, &keys);
ieee80211_link_debugfs_remove(link);
- ieee80211_link_stop(link);
+ stop[link_id] = link;
}
+ /* drain RCU readers before cancelling work they may queue */
synchronize_rcu();
+ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
+ if (stop[link_id])
+ ieee80211_link_stop(stop[link_id]);
+
ieee80211_free_key_list(sdata->local, &keys);
}
base-commit: 25e73f1d6868c759c8eb56cad4e411692c5341b4
--
2.56.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-28 14:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-28 14:17 [PATCH] wifi: mac80211: drain link readers before stopping removed links Zhao Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®