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: 306c54d0ed
("usb: hcd: Try MSI interrupts on PCI devices")
Reported-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/linux-usb/30a8c4ca-64c2-863b-cfcd-0970599c0ba3@huawei.com/
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200814182218.71957-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
bed97b3096
commit
7b2816dd29
|
@ -315,11 +315,14 @@ EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
|
||||||
void usb_hcd_pci_remove(struct pci_dev *dev)
|
void usb_hcd_pci_remove(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
struct usb_hcd *hcd;
|
struct usb_hcd *hcd;
|
||||||
|
int hcd_driver_flags;
|
||||||
|
|
||||||
hcd = pci_get_drvdata(dev);
|
hcd = pci_get_drvdata(dev);
|
||||||
if (!hcd)
|
if (!hcd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
hcd_driver_flags = hcd->driver->flags;
|
||||||
|
|
||||||
if (pci_dev_run_wake(dev))
|
if (pci_dev_run_wake(dev))
|
||||||
pm_runtime_get_noresume(&dev->dev);
|
pm_runtime_get_noresume(&dev->dev);
|
||||||
|
|
||||||
|
@ -347,7 +350,7 @@ void usb_hcd_pci_remove(struct pci_dev *dev)
|
||||||
up_read(&companions_rwsem);
|
up_read(&companions_rwsem);
|
||||||
}
|
}
|
||||||
usb_put_hcd(hcd);
|
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_free_irq_vectors(dev);
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue