lkml.org 
[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 329/563] rsi: Fix use-after-free in rsi_rx_done_handler()
    Date
    From: Zekun Shen <bruceshenzk@gmail.com>

    [ Upstream commit b07e3c6ebc0c20c772c0f54042e430acec2945c3 ]

    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
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/wireless/rsi/rsi_91x_usb.c | 8 +++++++-
    1 file changed, 7 insertions(+), 1 deletion(-)

    diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
    index d881df9ebd0c3..7f34148c7dfe5 100644
    --- a/drivers/net/wireless/rsi/rsi_91x_usb.c
    +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
    @@ -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)
    --
    2.34.1


    \
     
     \ /
      Last update: 2022-01-24 21:40    [W:7.765 / U:0.216 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site