Commit 7b2816dd authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Greg Kroah-Hartman
Browse files

usb: hcd: Fix use after free in usb_hcd_pci_remove()



On the removal stage we put a reference to the controller structure and
if it's not used anymore it gets freed, but later we try to dereference
a pointer to a member of that structure.

Copy necessary field to a temporary variable to avoid use after free.

Fixes: 306c54d0 ("usb: hcd: Try MSI interrupts on PCI devices")
Reported-by: default avatarJohn Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/linux-usb/30a8c4ca-64c2-863b-cfcd-0970599c0ba3@huawei.com/


Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200814182218.71957-1-andriy.shevchenko@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bed97b30
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -315,11 +315,14 @@ EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
void usb_hcd_pci_remove(struct pci_dev *dev)
{
	struct usb_hcd		*hcd;
	int			hcd_driver_flags;

	hcd = pci_get_drvdata(dev);
	if (!hcd)
		return;

	hcd_driver_flags = hcd->driver->flags;

	if (pci_dev_run_wake(dev))
		pm_runtime_get_noresume(&dev->dev);

@@ -347,7 +350,7 @@ void usb_hcd_pci_remove(struct pci_dev *dev)
		up_read(&companions_rwsem);
	}
	usb_put_hcd(hcd);
	if ((hcd->driver->flags & HCD_MASK) < HCD_USB3)
	if ((hcd_driver_flags & HCD_MASK) < HCD_USB3)
		pci_free_irq_vectors(dev);
	pci_disable_device(dev);
}