Skip to content

Commit e02a3b9

Browse files
pskrgaggregkh
authored andcommitted
staging: rtl8712: fix memory leak in rtl871x_load_fw_cb
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: 8c213fa ("staging: r8712u: Use asynchronous firmware loading") Signed-off-by: Pavel Skripkin <[email protected]> Link: https://lore.kernel.org/r/81e68fe0194499cc2e7692d35bc4dcf167827d8f.1623620630.git.paskripkin@gmail.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d1d3e3c commit e02a3b9

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

drivers/staging/rtl8712/hal_init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
4040
dev_err(&udev->dev, "r8712u: Firmware request failed\n");
4141
usb_put_dev(udev);
4242
usb_set_intfdata(usb_intf, NULL);
43+
r8712_free_drv_sw(adapter);
44+
adapter->dvobj_deinit(adapter);
4345
complete(&adapter->rtl8712_fw_ready);
46+
free_netdev(adapter->pnetdev);
4447
return;
4548
}
4649
adapter->fw = firmware;

0 commit comments

Comments
 (0)