From: 傅继晗 Commit d594cc6f2c58 ("wifi: mac80211: restore non-chanctx injection behaviour") restored the monitor injection fallback for drivers using chanctx emulation but explicitly deferred the harder case of drivers that transitioned to real chanctx ops. mt76 falls in that category and still drops every injected frame when monitor coexists with another interface. When the monitor has no chanctx of its own, fall back to the only chanctx in flight if there is exactly one. Refuse if multiple are present: picking arbitrarily would inject onto an unrelated channel. Reran the airgeddon evil-twin flow (hostapd AP + coexisting monitor VIF on the same phy + aireplay-ng deauth from the monitor) on mt7921e PCIe and mt7921u USB across 2.4 GHz and 5 GHz, and on a Kali VM with MT7921U passthrough as the closest match to the original reporter's setup. None reproduced the hang seen against the earlier attempt at this fix (<20251216111909.25076-2-johannes@sipsolutions.net>) or against v1 on lore in March. Cc: stable@vger.kernel.org # 6.9+ Reported-by: Oscar Alfonso Diaz Closes: https://github.com/morrownr/USB-WiFi/issues/682 Tested-by: Devin Wittmayer Fixes: 0a44dfc07074 ("wifi: mac80211: simplify non-chanctx drivers") Signed-off-by: 傅继晗 Signed-off-by: Devin Wittmayer --- v3: - Replace list_is_singular() + list_first_entry() with list_first_or_null_rcu() and an rcu_access_pointer() check that the entry is the only one in the list. The v2 pair re-read ->next without RCU between the singularity check and the entry fetch, racing list_del_rcu() of the sole entry (rculist.h). - Tested-by carries from v2: v3 changes the lookup primitive only, not the TX path, so the v2 airgeddon evil-twin flow on mt7921e/mt7921u/Kali-VM still applies. v2: - First respin under my submitter signoff; preserves fjh1997 authorship. - Verification matrix; airgeddon evil-twin flow on mt7921e/ mt7921u/Kali-VM does not reproduce the hang reported against the v1 attempt at this fix. net/mac80211/tx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 933c86ca21c3..6d2c71a13f26 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2407,12 +2407,20 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, rcu_dereference(tmp_sdata->vif.bss_conf.chanctx_conf); } - if (chanctx_conf) + if (chanctx_conf) { chandef = &chanctx_conf->def; - else if (local->emulate_chanctx) + } else if (local->emulate_chanctx) { chandef = &local->hw.conf.chandef; - else - goto fail_rcu; + } else { + struct ieee80211_chanctx *ctx; + + ctx = list_first_or_null_rcu(&local->chanctx_list, + struct ieee80211_chanctx, list); + if (!ctx || + rcu_access_pointer(ctx->list.next) != &local->chanctx_list) + goto fail_rcu; + chandef = &ctx->conf.def; + } /* * If driver/HW supports IEEE80211_CHAN_CAN_MONITOR we still