Skip to content

Commit

Permalink
rsi: Fix use-after-free in rsi_rx_done_handler()
Browse files Browse the repository at this point in the history
[ Upstream commit b07e3c6 ]

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]
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
buszk authored and whdgmawkd committed Feb 11, 2022
1 parent 52641f5 commit befdd9c
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/net/wireless/rsi/rsi_91x_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -294,8 +298,10 @@ static void rsi_rx_done_handler(struct urb *urb)
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)
Expand Down

0 comments on commit befdd9c

Please sign in to comment.