Message ID | 2b88f416-b2cb-7a18-d688-951e6dc3fe92@i-love.sakura.ne.jp (mailing list archive) |
---|---|
State | Accepted |
Commit | b0ec7e55fce65f125bd1d7f02e2dc4de62abee34 |
Delegated to: | Kalle Valo |
Headers | show |
Series | [1/2,(RESEND)] ath9k_htc: fix NULL pointer dereference at ath9k_htc_rxep() | expand |
Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> wrote: > syzbot is reporting lockdep warning followed by kernel panic at > ath9k_htc_rxep() [1], for ath9k_htc_rxep() depends on ath9k_rx_init() > being already completed. > > Since ath9k_htc_rxep() is set by ath9k_htc_connect_svc(WMI_BEACON_SVC) > from ath9k_init_htc_services(), it is possible that ath9k_htc_rxep() is > called via timer interrupt before ath9k_rx_init() from ath9k_init_device() > is called. > > Since we can't call ath9k_init_device() before ath9k_init_htc_services(), > let's hold ath9k_htc_rxep() no-op until ath9k_rx_init() completes. > > Link: https://syzkaller.appspot.com/bug?extid=4d2d56175b934b9a7bf9 [1] > Reported-by: syzbot <syzbot+4d2d56175b934b9a7bf9@syzkaller.appspotmail.com> > Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> > Tested-by: syzbot <syzbot+4d2d56175b934b9a7bf9@syzkaller.appspotmail.com> > Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> 2 patches applied to ath-next branch of ath.git, thanks. b0ec7e55fce6 ath9k_htc: fix NULL pointer dereference at ath9k_htc_rxep() 8b3046abc99e ath9k_htc: fix NULL pointer dereference at ath9k_htc_tx_get_packet()
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0a1634238e67..4f71e962279a 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -281,6 +281,7 @@ struct ath9k_htc_rxbuf { struct ath9k_htc_rx { struct list_head rxbuf; spinlock_t rxbuflock; + bool initialized; }; #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 8e69e8989f6d..0d4595ee51ba 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1130,6 +1130,9 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; unsigned long flags; + /* Check if ath9k_rx_init() completed. */ + if (!data_race(priv->rx.initialized)) + goto err; spin_lock_irqsave(&priv->rx.rxbuflock, flags); list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { if (!tmp_buf->in_process) { @@ -1185,6 +1188,9 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv) list_add_tail(&rxbuf->list, &priv->rx.rxbuf); } + /* Allow ath9k_htc_rxep() to operate. */ + smp_wmb(); + priv->rx.initialized = true; return 0; err: