diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2020-08-14 21:22:18 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-08-18 12:09:52 +0200 |
commit | 7b2816dd293031b9dec476d7853c099dc2ec9172 (patch) | |
tree | 0faaba5f81d2736abc89e76d99c61a45fe3765c3 /drivers/usb/core | |
parent | bed97b30968ba354035a020989df0623e52b5536 (diff) | |
download | linux-7b2816dd293031b9dec476d7853c099dc2ec9172.tar.bz2 |
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: 306c54d0edb6 ("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>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 4dc443aaef5c..ec0d6c50610c 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -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); } |