rsi: Fix use-after-free in rsi_rx_done_handler()
When freeing rx_cb->rx_skb, the pointer is not set to NULL, a later rsi_rx_done_handler call will try to read the freed address. This bug will very likley lead to double free, although detected early as use-after-free bug. The bug is triggerable with a compromised/malfunctional usb device. After applying the patch, the same input no longer triggers the use-after-free. Attached is the kasan report from fuzzing. BUG: KASAN: use-after-free in rsi_rx_done_handler+0x354/0x430 [rsi_usb] Read of size 4 at addr ffff8880188e5930 by task modprobe/231 Call Trace: <IRQ> dump_stack+0x76/0xa0 print_address_description.constprop.0+0x16/0x200 ? rsi_rx_done_handler+0x354/0x430 [rsi_usb] ? rsi_rx_done_handler+0x354/0x430 [rsi_usb] __kasan_report.cold+0x37/0x7c ? dma_direct_unmap_page+0x90/0x110 ? rsi_rx_done_handler+0x354/0x430 [rsi_usb] kasan_report+0xe/0x20 rsi_rx_done_handler+0x354/0x430 [rsi_usb] __usb_hcd_giveback_urb+0x1e4/0x380 usb_giveback_urb_bh+0x241/0x4f0 ? __usb_hcd_giveback_urb+0x380/0x380 ? apic_timer_interrupt+0xa/0x20 tasklet_action_common.isra.0+0x135/0x330 __do_softirq+0x18c/0x634 ? handle_irq_event+0xcd/0x157 ? handle_edge_irq+0x1eb/0x7b0 irq_exit+0x114/0x140 do_IRQ+0x91/0x1e0 common_interrupt+0xf/0xf </IRQ> Reported-by: Brendan Dolan-Gavitt <brendandg@nyu.edu> Signed-off-by: Zekun Shen <bruceshenzk@gmail.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/YXxQL/vIiYcZUu/j@10-18-43-117.dynapool.wireless.nyu.edu
This commit is contained in:
parent
7a6cfe28ae
commit
b07e3c6ebc
|
@ -269,8 +269,12 @@ static void rsi_rx_done_handler(struct urb *urb)
|
|||
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data;
|
||||
int status = -EINVAL;
|
||||
|
||||
if (!rx_cb->rx_skb)
|
||||
return;
|
||||
|
||||
if (urb->status) {
|
||||
dev_kfree_skb(rx_cb->rx_skb);
|
||||
rx_cb->rx_skb = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,8 +298,10 @@ out:
|
|||
if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC))
|
||||
rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__);
|
||||
|
||||
if (status)
|
||||
if (status) {
|
||||
dev_kfree_skb(rx_cb->rx_skb);
|
||||
rx_cb->rx_skb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rsi_rx_urb_kill(struct rsi_hw *adapter, u8 ep_num)
|
||||
|
|
Loading…
Reference in New Issue