Skip to content
  • Lukas Wunner's avatar
    PCI: pciehp: Fix use-after-free on unplug · 281e878e
    Lukas Wunner authored
    When pciehp is unbound (e.g. on unplug of a Thunderbolt device), the
    hotplug_slot struct is deregistered and thus freed before freeing the
    IRQ.  The IRQ handler and the work items it schedules print the slot
    name referenced from the freed structure in various informational and
    debug log messages, each time resulting in a quadruple dereference of
    freed pointers (hotplug_slot -> pci_slot -> kobject -> name).
    
    At best the slot name is logged as "(null)", at worst kernel memory is
    exposed in logs or the driver crashes:
    
      pciehp 0000:10:00.0:pcie204: Slot((null)): Card not present
    
    An attacker may provoke the bug by unplugging multiple devices on a
    Thunderbolt daisy chain at once.  Unplugging can also be simulated by
    powering down slots via sysfs.  The bug is particularly easy to trigger
    in poll mode.
    
    It has been present since the driver's introduction in 2004:
    https://git.kernel.org/tglx/history/c/c16b4b14d980
    
    
    
    Fix by rearranging teardown such that the IRQ is freed first.  Run the
    work items queued by the IRQ handler to completion before freeing the
    hotplug_slot struct by draining the work queue from the ->release_slot
    callback which is invoked by pci_hp_deregister().
    
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
    Cc: stable@vger.kernel.org # v2.6.4
    281e878e