ath9k: Fix use-after-free Write in ath9k_htc_rx_msg
authorQiujun Huang <hqjagain@gmail.com>
Sat, 4 Apr 2020 04:18:36 +0000 (12:18 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Jun 2020 08:24:12 +0000 (10:24 +0200)
commit e4ff08a4d727146bb6717a39a8d399d834654345 upstream.

Write out of slab bounds. We should check epid.

The case reported by syzbot:
https://lore.kernel.org/linux-usb/0000000000006ac55b05a1c05d72@google.com
BUG: KASAN: use-after-free in htc_process_conn_rsp
drivers/net/wireless/ath/ath9k/htc_hst.c:131 [inline]
BUG: KASAN: use-after-free in ath9k_htc_rx_msg+0xa25/0xaf0
drivers/net/wireless/ath/ath9k/htc_hst.c:443
Write of size 2 at addr ffff8881cea291f0 by task swapper/1/0

Call Trace:
 htc_process_conn_rsp drivers/net/wireless/ath/ath9k/htc_hst.c:131
[inline]
ath9k_htc_rx_msg+0xa25/0xaf0
drivers/net/wireless/ath/ath9k/htc_hst.c:443
ath9k_hif_usb_reg_in_cb+0x1ba/0x630
drivers/net/wireless/ath/ath9k/hif_usb.c:718
__usb_hcd_giveback_urb+0x29a/0x550 drivers/usb/core/hcd.c:1650
usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1716
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+b1c61e5f11be5782f192@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-4-hqjagain@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/ath/ath9k/htc_hst.c

index fd85f99..257b6ee 100644 (file)
@@ -114,6 +114,9 @@ static void htc_process_conn_rsp(struct htc_target *target,
 
        if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
                epid = svc_rspmsg->endpoint_id;
+               if (epid < 0 || epid >= ENDPOINT_MAX)
+                       return;
+
                service_id = be16_to_cpu(svc_rspmsg->service_id);
                max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
                endpoint = &target->endpoint[epid];