Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af707d9d authored by Rustam Kovhaev's avatar Rustam Kovhaev Committed by Greg Kroah-Hartman
Browse files

staging: rtl8712: handle firmware load failure



commit b4383c971bc5263efe2b0915ba67ebf2bf3f1ee5 upstream.

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: default avatar <syzbot+80899a8a8efe8968cde7@syzkaller.appspotmail.com>
Link: https://syzkaller.appspot.com/bug?extid=80899a8a8efe8968cde7


Signed-off-by: default avatarRustam 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: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6a7626c4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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";
+8 −3
Original line number Diff line number Diff line
@@ -595,12 +595,16 @@ 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;
		if (pnetdev->reg_state != NETREG_UNINITIALIZED)
			unregister_netdev(pnetdev); /* will call netdev_close() */
		flush_scheduled_work();
		udelay(1);
@@ -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.