Skip to content

Commit 8b3046a

Browse files
Tetsuo Handakvalo
Tetsuo Handa
authored andcommitted
ath9k_htc: fix NULL pointer dereference at ath9k_htc_tx_get_packet()
syzbot is reporting lockdep warning at ath9k_wmi_event_tasklet() followed by kernel panic at get_htc_epid_queue() from ath9k_htc_tx_get_packet() from ath9k_htc_txstatus() [1], for ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) depends on spin_lock_init() from ath9k_init_priv() being already completed. Since ath9k_wmi_event_tasklet() is set by ath9k_init_wmi() from ath9k_htc_probe_device(), it is possible that ath9k_wmi_event_tasklet() is called via tasklet interrupt before spin_lock_init() from ath9k_init_priv() from ath9k_init_device() from ath9k_htc_probe_device() is called. Let's hold ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) no-op until ath9k_tx_init() completes. Link: https://syzkaller.appspot.com/bug?extid=31d54c60c5b254d6f75b [1] Reported-by: syzbot <[email protected]> Signed-off-by: Tetsuo Handa <[email protected]> Tested-by: syzbot <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b0ec7e5 commit 8b3046a

File tree

3 files changed

+10
-0
lines changed

3 files changed

+10
-0
lines changed

drivers/net/wireless/ath/ath9k/htc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ struct ath9k_htc_tx {
306306
DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
307307
struct timer_list cleanup_timer;
308308
spinlock_t tx_lock;
309+
bool initialized;
309310
};
310311

311312
struct ath9k_htc_tx_ctl {

drivers/net/wireless/ath/ath9k/htc_drv_txrx.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,11 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv)
813813
skb_queue_head_init(&priv->tx.data_vi_queue);
814814
skb_queue_head_init(&priv->tx.data_vo_queue);
815815
skb_queue_head_init(&priv->tx.tx_failed);
816+
817+
/* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */
818+
smp_wmb();
819+
priv->tx.initialized = true;
820+
816821
return 0;
817822
}
818823

drivers/net/wireless/ath/ath9k/wmi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t)
169169
&wmi->drv_priv->fatal_work);
170170
break;
171171
case WMI_TXSTATUS_EVENTID:
172+
/* Check if ath9k_tx_init() completed. */
173+
if (!data_race(priv->tx.initialized))
174+
break;
175+
172176
spin_lock_bh(&priv->tx.tx_lock);
173177
if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
174178
spin_unlock_bh(&priv->tx.tx_lock);

0 commit comments

Comments
 (0)