staging: rtl8712: handle firmware load failure
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: syzbot+80899a8a8efe8968cde7@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=80899a8a8efe8968cde7 Signed-off-by: Rustam Kovhaev <rkovhaev@gmail.com> Cc: stable <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20200716151324.1036204-1-rkovhaev@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c4283950a9
commit
b4383c971b
|
@ -33,7 +33,6 @@ 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;
|
||||
|
@ -41,11 +40,13 @@ 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);
|
||||
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";
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue