Thread (8 messages) flat view 8 messages, 2 authors, 2021-10-02

Re: [PATCH] net: ath9k: fix use-after-free in ath9k_hif_usb_rx_cb

From: Pavel Skripkin <hidden>
Date: 2021-08-31 10:43:58
Also in: lkml, netdev

On 8/4/21 10:57 PM, Pavel Skripkin wrote:
On 8/4/21 10:48 PM, Pavel Skripkin wrote:
quoted
Syzbot reported use-after-free Read in ath9k_hif_usb_rx_cb(). The
problem was in incorrect htc_handle->drv_priv initialization.

Probable call trace which can trigger use-after-free:

ath9k_htc_probe_device()
   /* htc_handle->drv_priv = priv; */
   ath9k_htc_wait_for_target()      <--- Failed
   ieee80211_free_hw()		   <--- priv pointer is freed

<IRQ>
...
ath9k_hif_usb_rx_cb()
   ath9k_hif_usb_rx_stream()
    RX_STAT_INC()		<--- htc_handle->drv_priv access

In order to not add fancy protection for drv_priv we can move
htc_handle->drv_priv initialization at the end of the
ath9k_htc_probe_device() and add helper macro to make
all *_STAT_* macros NULL save.

Also, I made whitespaces clean ups in *_STAT_* macros definitions
to make checkpatch.pl happy.

Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
Reported-and-tested-by: syzbot+03110230a11411024147@syzkaller.appspotmail.com
Signed-off-by: Pavel Skripkin <redacted>
---

Hi, ath9k maintainer/developers!

I know, that you do not like changes, that wasn't tested on real
hardware. I really don't access to this one, so I'd like you to test it on
real hardware piece, if you have one. At least, this patch was tested by
syzbot [1]

[1] https://syzkaller.appspot.com/bug?id=6ead44e37afb6866ac0c7dd121b4ce07cb665f60

---
  drivers/net/wireless/ath/ath9k/htc.h          | 11 ++++++-----
  drivers/net/wireless/ath/ath9k/htc_drv_init.c |  3 ++-
  2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 0a1634238e67..c16b2a482e83 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -326,11 +326,12 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
  
  #ifdef CONFIG_ATH9K_HTC_DEBUGFS
  
-#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
-#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
-#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
-#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
-#define CAB_STAT_INC   priv->debug.tx_stats.cab_queued++
+#define __STAT_SAVE(expr)	(hif_dev->htc_handle->drv_priv ? (expr) : 0)
+#define TX_STAT_INC(c)		__STAT_SAVE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
+#define TX_STAT_ADD(c, a)	__STAT_SAVE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
+#define RX_STAT_INC(c)		__STAT_SAVE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
+#define RX_STAT_ADD(c, a)	__STAT_SAVE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
+#define CAB_STAT_INC		(priv->debug.tx_stats.cab_queued++)
  
  #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
  
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index ff61ae34ecdf..07ac88fb1c57 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -944,7 +944,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
  	priv->hw = hw;
  	priv->htc = htc_handle;
  	priv->dev = dev;
-	htc_handle->drv_priv = priv;
  	SET_IEEE80211_DEV(hw, priv->dev);
  
  	ret = ath9k_htc_wait_for_target(priv);
@@ -965,6 +964,8 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
  	if (ret)
  		goto err_init;
  
+	htc_handle->drv_priv = priv;
+
  	return 0;
  
  err_init:
Added missing LKML in CC. Sorry for confusion.
Any chance to review this patch? Thanks




With regards,
Pavel Skripkin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help