lkml.org 
[lkml]   [2021]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 719/800] staging: rtl8712: fix memory leak in rtl871x_load_fw_cb
    Date
    From: Pavel Skripkin <paskripkin@gmail.com>

    [ Upstream commit e02a3b945816a77702a2769a70ef5f9b06e49d54 ]

    There is a leak in rtl8712 driver.
    The problem was in non-freed adapter data if
    firmware load failed.

    This leak can be reproduced with this code:
    https://syzkaller.appspot.com/text?tag=ReproC&x=16612f02d00000,
    Autoload must fail (to not hit memory leak reported by syzkaller)

    There are 2 possible ways how rtl871x_load_fw_cb() and
    r871xu_dev_remove() can be called (in case of fw load error).

    1st case:
    r871xu_dev_remove() then rtl871x_load_fw_cb()

    In this case r871xu_dev_remove() will wait for
    completion and then will jump to the end, because
    rtl871x_load_fw_cb() set intfdata to NULL:

    if (pnetdev) {
    struct _adapter *padapter = netdev_priv(pnetdev);

    /* never exit with a firmware callback pending */
    wait_for_completion(&padapter->rtl8712_fw_ready);
    pnetdev = usb_get_intfdata(pusb_intf);
    usb_set_intfdata(pusb_intf, NULL);
    if (!pnetdev)
    goto firmware_load_fail;

    ... clean up code here ...
    }

    2nd case:
    rtl871x_load_fw_cb() then r871xu_dev_remove()

    In this case pnetdev (from code snippet above) will
    be zero (because rtl871x_load_fw_cb() set it to NULL)
    And clean up code won't be executed again.

    So, in all cases we need to free adapted data in rtl871x_load_fw_cb(),
    because disconnect function cannot take care of it. And there won't be
    any race conditions, because complete() call happens after setting
    intfdata to NULL.

    In previous patch I moved out free_netdev() from r8712_free_drv_sw()
    and that's why now it's possible to free adapter data and then call
    complete.

    Fixes: 8c213fa59199 ("staging: r8712u: Use asynchronous firmware loading")
    Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
    Link: https://lore.kernel.org/r/81e68fe0194499cc2e7692d35bc4dcf167827d8f.1623620630.git.paskripkin@gmail.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/staging/rtl8712/hal_init.c | 3 +++
    1 file changed, 3 insertions(+)

    diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
    index 715f1fe8b472..22974277afa0 100644
    --- a/drivers/staging/rtl8712/hal_init.c
    +++ b/drivers/staging/rtl8712/hal_init.c
    @@ -40,7 +40,10 @@ static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
    dev_err(&udev->dev, "r8712u: Firmware request failed\n");
    usb_put_dev(udev);
    usb_set_intfdata(usb_intf, NULL);
    + r8712_free_drv_sw(adapter);
    + adapter->dvobj_deinit(adapter);
    complete(&adapter->rtl8712_fw_ready);
    + free_netdev(adapter->pnetdev);
    return;
    }
    adapter->fw = firmware;
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-12 10:53    [W:4.023 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site