Skip to content

Commit b07e3c6

Browse files
buszkKalle Valo
authored and
Kalle Valo
committed
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 <[email protected]> Signed-off-by: Zekun Shen <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/YXxQL/vIiYcZUu/[email protected]
1 parent 7a6cfe2 commit b07e3c6

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

drivers/net/wireless/rsi/rsi_91x_usb.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,12 @@ static void rsi_rx_done_handler(struct urb *urb)
269269
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data;
270270
int status = -EINVAL;
271271

272+
if (!rx_cb->rx_skb)
273+
return;
274+
272275
if (urb->status) {
273276
dev_kfree_skb(rx_cb->rx_skb);
277+
rx_cb->rx_skb = NULL;
274278
return;
275279
}
276280

@@ -294,8 +298,10 @@ static void rsi_rx_done_handler(struct urb *urb)
294298
if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC))
295299
rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__);
296300

297-
if (status)
301+
if (status) {
298302
dev_kfree_skb(rx_cb->rx_skb);
303+
rx_cb->rx_skb = NULL;
304+
}
299305
}
300306

301307
static void rsi_rx_urb_kill(struct rsi_hw *adapter, u8 ep_num)

0 commit comments

Comments
 (0)