ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb
authorQiujun Huang <hqjagain@gmail.com>
Sat, 4 Apr 2020 04:18:37 +0000 (12:18 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 7 Apr 2020 04:57:06 +0000 (07:57 +0300)
Add barrier to accessing the stack array skb_pool.

The case reported by syzbot:
https://lore.kernel.org/linux-usb/0000000000003d7c1505a2168418@google.com
BUG: KASAN: stack-out-of-bounds in ath9k_hif_usb_rx_stream
drivers/net/wireless/ath/ath9k/hif_usb.c:626 [inline]
BUG: KASAN: stack-out-of-bounds in ath9k_hif_usb_rx_cb+0xdf6/0xf70
drivers/net/wireless/ath/ath9k/hif_usb.c:666
Write of size 8 at addr ffff8881db309a28 by task swapper/1/0

Call Trace:
ath9k_hif_usb_rx_stream drivers/net/wireless/ath/ath9k/hif_usb.c:626
[inline]
ath9k_hif_usb_rx_cb+0xdf6/0xf70
drivers/net/wireless/ath/ath9k/hif_usb.c:666
__usb_hcd_giveback_urb+0x1f2/0x470 drivers/usb/core/hcd.c:1648
usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1713
dummy_timer+0x1258/0x32ae drivers/usb/gadget/udc/dummy_hcd.c:1966
call_timer_fn+0x195/0x6f0 kernel/time/timer.c:1404
expire_timers kernel/time/timer.c:1449 [inline]
__run_timers kernel/time/timer.c:1773 [inline]
__run_timers kernel/time/timer.c:1740 [inline]
run_timer_softirq+0x5f9/0x1500 kernel/time/timer.c:1786

Reported-and-tested-by: syzbot+d403396d4df67ad0bd5f@syzkaller.appspotmail.com
Signed-off-by: Qiujun Huang <hqjagain@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200404041838.10426-5-hqjagain@gmail.com
drivers/net/wireless/ath/ath9k/hif_usb.c

index f227e19..6049d37 100644 (file)
@@ -612,6 +612,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
                        hif_dev->remain_skb = nskb;
                        spin_unlock(&hif_dev->rx_lock);
                } else {
+                       if (pool_index == MAX_PKT_NUM_IN_TRANSFER) {
+                               dev_err(&hif_dev->udev->dev,
+                                       "ath9k_htc: over RX MAX_PKT_NUM\n");
+                               goto err;
+                       }
                        nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
                        if (!nskb) {
                                dev_err(&hif_dev->udev->dev,