lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <2024122724-CVE-2024-53194-9edf@gregkh>
Date: Fri, 27 Dec 2024 14:52:40 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-cve-announce@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: CVE-2024-53194: PCI: Fix use-after-free of slot->bus on hot remove

Description
===========

In the Linux kernel, the following vulnerability has been resolved:

PCI: Fix use-after-free of slot->bus on hot remove

Dennis reports a boot crash on recent Lenovo laptops with a USB4 dock.

Since commit 0fc70886569c ("thunderbolt: Reset USB4 v2 host router") and
commit 59a54c5f3dbd ("thunderbolt: Reset topology created by the boot
firmware"), USB4 v2 and v1 Host Routers are reset on probe of the
thunderbolt driver.

The reset clears the Presence Detect State and Data Link Layer Link Active
bits at the USB4 Host Router's Root Port and thus causes hot removal of the
dock.

The crash occurs when pciehp is unbound from one of the dock's Downstream
Ports:  pciehp creates a pci_slot on bind and destroys it on unbind.  The
pci_slot contains a pointer to the pci_bus below the Downstream Port, but
a reference on that pci_bus is never acquired.  The pci_bus is destroyed
before the pci_slot, so a use-after-free ensues when pci_slot_release()
accesses slot->bus.

In principle this should not happen because pci_stop_bus_device() unbinds
pciehp (and therefore destroys the pci_slot) before the pci_bus is
destroyed by pci_remove_bus_device().

However the stacktrace provided by Dennis shows that pciehp is unbound from
pci_remove_bus_device() instead of pci_stop_bus_device().  To understand
the significance of this, one needs to know that the PCI core uses a two
step process to remove a portion of the hierarchy:  It first unbinds all
drivers in the sub-hierarchy in pci_stop_bus_device() and then actually
removes the devices in pci_remove_bus_device().  There is no precaution to
prevent driver binding in-between pci_stop_bus_device() and
pci_remove_bus_device().

In Dennis' case, it seems removal of the hierarchy by pciehp races with
driver binding by pci_bus_add_devices().  pciehp is bound to the
Downstream Port after pci_stop_bus_device() has run, so it is unbound by
pci_remove_bus_device() instead of pci_stop_bus_device().  Because the
pci_bus has already been destroyed at that point, accesses to it result in
a use-after-free.

One might conclude that driver binding needs to be prevented after
pci_stop_bus_device() has run.  However it seems risky that pci_slot points
to pci_bus without holding a reference.  Solely relying on correct ordering
of driver unbind versus pci_bus destruction is certainly not defensive
programming.

If pci_slot has a need to access data in pci_bus, it ought to acquire a
reference.  Amend pci_create_slot() accordingly.  Dennis reports that the
crash is not reproducible with this change.

Abridged stacktrace:

  pcieport 0000:00:07.0: PME: Signaling with IRQ 156
  pcieport 0000:00:07.0: pciehp: Slot #12 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+
  pci_bus 0000:20: dev 00, created physical slot 12
  pcieport 0000:00:07.0: pciehp: Slot(12): Card not present
  ...
  pcieport 0000:21:02.0: pciehp: pcie_disable_notification: SLOTCTRL d8 write cmd 0
  Oops: general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b6b: 0000 [#1] PREEMPT SMP NOPTI
  CPU: 13 UID: 0 PID: 134 Comm: irq/156-pciehp Not tainted 6.11.0-devel+ #1
  RIP: 0010:dev_driver_string+0x12/0x40
  pci_destroy_slot
  pciehp_remove
  pcie_port_remove_service
  device_release_driver_internal
  bus_remove_device
  device_del
  device_unregister
  remove_iter
  device_for_each_child
  pcie_portdrv_remove
  pci_device_remove
  device_release_driver_internal
  bus_remove_device
  device_del
  pci_remove_bus_device (recursive invocation)
  pci_remove_bus_device
  pciehp_unconfigure_device
  pciehp_disable_slot
  pciehp_handle_presence_or_link_change
  pciehp_ist

The Linux kernel CVE team has assigned CVE-2024-53194 to this issue.


Affected and fixed versions
===========================

	Fixed in 4.19.325 with commit 50473dd3b2a08601a078f852ea05572de9b1f86c
	Fixed in 5.4.287 with commit d0ddd2c92b75a19a37c887154223372b600fed37
	Fixed in 5.10.231 with commit da6e6ff1f6c57f16e07af955e0e997fc90dd1e75
	Fixed in 5.15.174 with commit 41bbb1eb996be1435815aa1fbcc9ffc45b84cc12
	Fixed in 6.1.120 with commit 20502f0b3f3acd6bee300257556c27a867f80c8b
	Fixed in 6.6.64 with commit e5d5c04aac71bf1476dc44b56f2206a4c2facca8
	Fixed in 6.11.11 with commit c8266ab8e7ccd1d1f5a9c8b29eb2020175048134
	Fixed in 6.12.2 with commit 69d2ceac11acf8579d58d55c9c5b65fb658f916e
	Fixed in 6.13-rc1 with commit c7acef99642b763ba585f4a43af999fcdbcc3dc4

Please see https://www.kernel.org for a full list of currently supported
kernel versions by the kernel community.

Unaffected versions might change over time as fixes are backported to
older supported kernel versions.  The official CVE entry at
	https://cve.org/CVERecord/?id=CVE-2024-53194
will be updated if fixes are backported, please check that for the most
up to date information about this issue.


Affected files
==============

The file(s) affected by this issue are:
	drivers/pci/slot.c


Mitigation
==========

The Linux kernel CVE team recommends that you update to the latest
stable kernel version for this, and many other bugfixes.  Individual
changes are never tested alone, but rather are part of a larger kernel
release.  Cherry-picking individual commits is not recommended or
supported by the Linux kernel community at all.  If however, updating to
the latest release is impossible, the individual changes to resolve this
issue can be found at these commits:
	https://git.kernel.org/stable/c/50473dd3b2a08601a078f852ea05572de9b1f86c
	https://git.kernel.org/stable/c/d0ddd2c92b75a19a37c887154223372b600fed37
	https://git.kernel.org/stable/c/da6e6ff1f6c57f16e07af955e0e997fc90dd1e75
	https://git.kernel.org/stable/c/41bbb1eb996be1435815aa1fbcc9ffc45b84cc12
	https://git.kernel.org/stable/c/20502f0b3f3acd6bee300257556c27a867f80c8b
	https://git.kernel.org/stable/c/e5d5c04aac71bf1476dc44b56f2206a4c2facca8
	https://git.kernel.org/stable/c/c8266ab8e7ccd1d1f5a9c8b29eb2020175048134
	https://git.kernel.org/stable/c/69d2ceac11acf8579d58d55c9c5b65fb658f916e
	https://git.kernel.org/stable/c/c7acef99642b763ba585f4a43af999fcdbcc3dc4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ