Skip to content

Commit

Permalink
staging: rtl8712: handle firmware load failure
Browse files Browse the repository at this point in the history
when firmware fails to load we should not call unregister_netdev()
this patch fixes a race condition between rtl871x_load_fw_cb() and
r871xu_dev_remove() and fixes the bug reported by syzbot

Reported-by: [email protected]
Link: https://syzkaller.appspot.com/bug?extid=80899a8a8efe8968cde7
Signed-off-by: Rustam Kovhaev <[email protected]>
Cc: stable <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
rustylife authored and gregkh committed Jul 17, 2020
1 parent c428395 commit b4383c9
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
3 changes: 2 additions & 1 deletion drivers/staging/rtl8712/hal_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,20 @@ static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
{
struct _adapter *adapter = context;

complete(&adapter->rtl8712_fw_ready);
if (!firmware) {
struct usb_device *udev = adapter->dvobjpriv.pusbdev;
struct usb_interface *usb_intf = adapter->pusb_intf;

dev_err(&udev->dev, "r8712u: Firmware request failed\n");
usb_put_dev(udev);
usb_set_intfdata(usb_intf, NULL);
complete(&adapter->rtl8712_fw_ready);
return;
}
adapter->fw = firmware;
/* firmware available - start netdev */
register_netdev(adapter->pnetdev);
complete(&adapter->rtl8712_fw_ready);
}

static const char firmware_file[] = "rtlwifi/rtl8712u.bin";
Expand Down
11 changes: 8 additions & 3 deletions drivers/staging/rtl8712/usb_intf.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,13 +595,17 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
if (pnetdev) {
struct _adapter *padapter = netdev_priv(pnetdev);

usb_set_intfdata(pusb_intf, NULL);
release_firmware(padapter->fw);
/* 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;
release_firmware(padapter->fw);
if (drvpriv.drv_registered)
padapter->surprise_removed = true;
unregister_netdev(pnetdev); /* will call netdev_close() */
if (pnetdev->reg_state != NETREG_UNINITIALIZED)
unregister_netdev(pnetdev); /* will call netdev_close() */
flush_scheduled_work();
udelay(1);
/* Stop driver mlme relation timer */
Expand All @@ -614,6 +618,7 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
*/
usb_put_dev(udev);
}
firmware_load_fail:
/* If we didn't unplug usb dongle and remove/insert module, driver
* fails on sitesurvey for the first time when device is up.
* Reset usb port for sitesurvey fail issue.
Expand Down

0 comments on commit b4383c9

Please sign in to comment.