CVE-2024-53194

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
Configurations

Configuration 1 (hide)

OR cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*

History

24 Mar 2025, 17:34

Type Values Removed Values Added
First Time Linux linux Kernel
Linux
References () https://git.kernel.org/stable/c/20502f0b3f3acd6bee300257556c27a867f80c8b - () https://git.kernel.org/stable/c/20502f0b3f3acd6bee300257556c27a867f80c8b - Patch
References () https://git.kernel.org/stable/c/41bbb1eb996be1435815aa1fbcc9ffc45b84cc12 - () https://git.kernel.org/stable/c/41bbb1eb996be1435815aa1fbcc9ffc45b84cc12 - Patch
References () https://git.kernel.org/stable/c/50473dd3b2a08601a078f852ea05572de9b1f86c - () https://git.kernel.org/stable/c/50473dd3b2a08601a078f852ea05572de9b1f86c - Patch
References () https://git.kernel.org/stable/c/69d2ceac11acf8579d58d55c9c5b65fb658f916e - () https://git.kernel.org/stable/c/69d2ceac11acf8579d58d55c9c5b65fb658f916e - Patch
References () https://git.kernel.org/stable/c/c7acef99642b763ba585f4a43af999fcdbcc3dc4 - () https://git.kernel.org/stable/c/c7acef99642b763ba585f4a43af999fcdbcc3dc4 - Patch
References () https://git.kernel.org/stable/c/c8266ab8e7ccd1d1f5a9c8b29eb2020175048134 - () https://git.kernel.org/stable/c/c8266ab8e7ccd1d1f5a9c8b29eb2020175048134 - Patch
References () https://git.kernel.org/stable/c/d0ddd2c92b75a19a37c887154223372b600fed37 - () https://git.kernel.org/stable/c/d0ddd2c92b75a19a37c887154223372b600fed37 - Patch
References () https://git.kernel.org/stable/c/da6e6ff1f6c57f16e07af955e0e997fc90dd1e75 - () https://git.kernel.org/stable/c/da6e6ff1f6c57f16e07af955e0e997fc90dd1e75 - Patch
References () https://git.kernel.org/stable/c/e5d5c04aac71bf1476dc44b56f2206a4c2facca8 - () https://git.kernel.org/stable/c/e5d5c04aac71bf1476dc44b56f2206a4c2facca8 - Patch
CPE cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*

11 Feb 2025, 16:15

Type Values Removed Values Added
CWE CWE-416
CVSS v2 : unknown
v3 : unknown
v2 : unknown
v3 : 7.8
Summary
  • (es) En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: PCI: Fix use-after-free of slot->bus on hot remove Dennis informa un fallo de arranque en portátiles Lenovo recientes con un dock USB4. Desde el commit 0fc70886569c ("thunderbolt: Reset USB4 v2 host router") y el commit 59a54c5f3dbd ("thunderbolt: Reset topology created by the boot firmware"), los routers host USB4 v2 y v1 se restablecen al sondear el controlador Thunderbolt. El restablecimiento borra los bits de estado de detección de presencia y de enlace de capa de enlace de datos activo en el puerto raíz del router host USB4 y, por lo tanto, provoca la eliminación en caliente del dock. El fallo se produce cuando pciehp se desvincula de uno de los puertos de bajada del dock: pciehp crea un pci_slot al vincularlo y lo destruye al desvincularlo. El pci_slot contiene un puntero al pci_bus debajo del puerto de bajada, pero nunca se adquiere una referencia en ese pci_bus. El pci_bus se destruye antes que el pci_slot, por lo que se produce un use-after-free cuando pci_slot_release() accede a slot->bus. En principio, esto no debería suceder porque pci_stop_bus_device() desvincula pciehp (y, por lo tanto, destruye el pci_slot) antes de que pci_remove_bus_device() destruya el pci_bus. Sin embargo, el seguimiento de la pila proporcionado por Dennis muestra que pciehp se desvincula de pci_remove_bus_device() en lugar de pci_stop_bus_device(). Para comprender la importancia de esto, es necesario saber que el núcleo PCI utiliza un proceso de dos pasos para eliminar una parte de la jerarquía: primero desvincula todos los controladores en la subjerarquía en pci_stop_bus_device() y luego elimina los dispositivos en pci_remove_bus_device(). No hay ninguna precaución para evitar la vinculación del controlador entre pci_stop_bus_device() y pci_remove_bus_device(). En el caso de Dennis, parece que la eliminación de la jerarquía por parte de pciehp compite con la vinculación del controlador por parte de pci_bus_add_devices(). pciehp está vinculado al puerto descendente después de que se haya ejecutado pci_stop_bus_device(), por lo que se desvincula mediante pci_remove_bus_device() en lugar de pci_stop_bus_device(). Debido a que pci_bus ya se ha destruido en ese punto, los accesos a él dan como resultado un use-after-free. Se podría concluir que es necesario evitar la vinculación del controlador después de que se haya ejecutado pci_stop_bus_device(). Sin embargo, parece arriesgado que pci_slot apunte a pci_bus sin contener una referencia. Confiar únicamente en el orden correcto de la desvinculación del controlador frente a la destrucción de pci_bus ciertamente no es programación defensiva. Si pci_slot necesita acceder a datos en pci_bus, debe adquirir una referencia. Modifique pci_create_slot() en consecuencia. Dennis informa que el bloqueo no se puede reproducir con este cambio. Rastreo de pila abreviado: pcieport 0000:00:07.0: PME: Señalización con IRQ 156 pcieport 0000:00:07.0: pciehp: Ranura n.º 12 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+ pci_bus 0000:20: dev 00, creó la ranura física 12 pcieport 0000:00:07.0: pciehp: Ranura (12): Tarjeta no presente... pcieport 0000:21:02.0: pciehp: pcie_disable_notification: SLOTCTRL d8 comando de escritura 0 Oops: error de protección general, probablemente para una dirección no canónica 0x6b6b6b6b6b6b6b6b6b: 0000 [#1] PREEMPT SMP NOPTI CPU: 13 UID: 0 PID: 134 Comm: irq/156-pciehp No contaminado 6.11.0-devel+ #1 RIP: 0010:dev_driver_string+0x12/0x40 ranura de destrucción pci pciehp_remove servicio de eliminación de puerto pcie dispositivo de liberación de controlador interno de bus eliminar dispositivo_eliminar_dispositivo anular_registro_dispositivo eliminar_iter dispositivo_para_cada_hijo_eliminar_puerto_pcie dispositivo_eliminar_dispositivo_liberación_controlador_interno_bus_eliminar_dispositivo dispositivo_eliminar pci_remove_bus_device (invocación recursiva) -- truncado----

27 Dec 2024, 14:15

Type Values Removed Values Added
New CVE

Information

Published : 2024-12-27 14:15

Updated : 2025-03-24 17:34


NVD link : CVE-2024-53194

Mitre link : CVE-2024-53194

CVE.ORG link : CVE-2024-53194


JSON object : View

Products Affected

linux

  • linux_kernel
CWE
CWE-416

Use After Free