Re: [BUG] ath9k_htc_tx_cleanup_timer -- ODEBUG free-active-timer and use-after-free on USB unplug
From: Chad Aldreda
Date: Mon Nov 09 2026 - 05:37:44 EST
Hi Farhad,
Could you share the reproducer for this one?
Two paths in the code would fit the report. Both end the same way:
the timer re-arms itself (ath9k_htc_tx_cleanup_timer()), and nothing
deletes it before ath9k_htc_disconnect_device() frees the hw.
1. ath9k_fatal_work() calls ath9k_htc_reset(), which re-arms
tx.cleanup_timer without checking ATH_OP_INVALID. A WMI_FATAL_EVENTID
(or beacon-stuck SWBA) that arrives after ath9k_htc_stop() has
finished still queues fatal_work, since WMI events are processed
until ath9k_stop_wmi(). The timer is then armed on a stopped device,
and ieee80211_unregister_hw() does not call stop again.
2. Inside ath9k_htc_stop(), the timer is deleted and priv->mutex is
dropped before cancel_work_sync(&priv->fatal_work). A fatal_work
already waiting on the mutex runs the reset in that gap and re-arms
the timer.
I'd like to know which one your reproducer hits before proposing a
fix. Does it send WMI_FATAL_EVENTID (or let beacons go stuck in
AP/IBSS/mesh mode), and is the interface up or down when it does?
The code reading above was done with an AI assistant (Claude). Nothing
has been tested yet.
Thanks,
Chad