diff mbox series

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

Message ID 20210922164204.32680-1-paskripkin@gmail.com (mailing list archive)
State Superseded
Delegated to: Kalle Valo
Headers show
Series [RESEND] net: ath9k: fix use-after-free in ath9k_hif_usb_rx_cb | expand

Commit Message

Pavel Skripkin Sept. 22, 2021, 4:42 p.m. UTC
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.

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

Why resend?
	No activity on this patch since 8/6/21, Kalle Valo has asked around,
	for review and no one claimed it.

Resend changes:
	1. Rebased on top of v5.15-rc2
	2. Removed clean ups for macros
	3. Added 1 more syzbot tag, since this patch has passed 2 syzbot
	tests

---
 drivers/net/wireless/ath/ath9k/htc.h          | 10 +++++-----
 drivers/net/wireless/ath/ath9k/htc_drv_init.c |  3 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

Comments

Pavel Skripkin Oct. 2, 2021, 1:05 p.m. UTC | #1
On 9/22/21 19:42, Pavel Skripkin wrote:
> 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.
> 
> Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
> Reported-and-tested-by: syzbot+03110230a11411024147@syzkaller.appspotmail.com
> Reported-and-tested-by: syzbot+c6dde1f690b60e0b9fbe@syzkaller.appspotmail.com
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
> 
> Why resend?
> 	No activity on this patch since 8/6/21, Kalle Valo has asked around,
> 	for review and no one claimed it.
> 
> Resend changes:
> 	1. Rebased on top of v5.15-rc2
> 	2. Removed clean ups for macros
> 	3. Added 1 more syzbot tag, since this patch has passed 2 syzbot
> 	tests
> 

Hi, ath9k maintainers!

Does this patch need any further work? I can't see any comments on it 
since 8/6/21 and I can't see it on wireless patchwork.

If this bug is already fixed and I've overlooked a fix commit, please, 
let me know. As I see syzbot hits this bug really often [1]

Thanks


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




With regards,
Pavel Skripkin
Kalle Valo Oct. 2, 2021, 1:11 p.m. UTC | #2
Pavel Skripkin <paskripkin@gmail.com> writes:

> On 9/22/21 19:42, Pavel Skripkin wrote:
>> 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.
>>
>> Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
>> Reported-and-tested-by: syzbot+03110230a11411024147@syzkaller.appspotmail.com
>> Reported-and-tested-by: syzbot+c6dde1f690b60e0b9fbe@syzkaller.appspotmail.com
>> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
>> ---
>>
>> Why resend?
>> 	No activity on this patch since 8/6/21, Kalle Valo has asked around,
>> 	for review and no one claimed it.
>>
>> Resend changes:
>> 	1. Rebased on top of v5.15-rc2
>> 	2. Removed clean ups for macros
>> 	3. Added 1 more syzbot tag, since this patch has passed 2 syzbot
>> 	tests
>>
>
> Hi, ath9k maintainers!
>
> Does this patch need any further work? I can't see any comments on it
> since 8/6/21 and I can't see it on wireless patchwork.
>
> If this bug is already fixed and I've overlooked a fix commit, please,
> let me know. As I see syzbot hits this bug really often [1]

See my other mail I just sent about ath9k syzbot patches:

https://lore.kernel.org/linux-wireless/87tuhzhdyq.fsf@codeaurora.org/

In summary: please wait patiently once I'm able to test the syzbot
patches on a real device.
Pavel Skripkin Oct. 2, 2021, 1:14 p.m. UTC | #3
On 10/2/21 16:11, Kalle Valo wrote:
>> Hi, ath9k maintainers!
>>
>> Does this patch need any further work? I can't see any comments on it
>> since 8/6/21 and I can't see it on wireless patchwork.
>>
>> If this bug is already fixed and I've overlooked a fix commit, please,
>> let me know. As I see syzbot hits this bug really often [1]
> 
> See my other mail I just sent about ath9k syzbot patches:
> 
> https://lore.kernel.org/linux-wireless/87tuhzhdyq.fsf@codeaurora.org/
> 
> In summary: please wait patiently once I'm able to test the syzbot
> patches on a real device.
> 

I see, thank you clarifying the situation. I understand, that 
maintaining ath9k devices alone is not easy task

Thanks again


With regards,
Pavel Skripkin
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 0a1634238e67..c8cde2e05d77 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -325,11 +325,11 @@  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 __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: