IM
IronMonkey Threat Research

CVE-2024-35809 MEDIUM

Published: 2024-05-17 | Last Modified: 2025-12-23 | Status: Analyzed

Description

In the Linux kernel, the following vulnerability has been resolved: PCI/PM: Drain runtime-idle callbacks before driver removal A race condition between the .runtime_idle() callback and the .remove() callback in the rtsx_pcr PCI driver leads to a kernel crash due to an unhandled page fault [1]. The problem is that rtsx_pci_runtime_idle() is not expected to be running after pm_runtime_get_sync() has been called, but the latter doesn't really guarantee that. It only guarantees that the suspend and resume callbacks will not be running when it returns. However, if a .runtime_idle() callback is already running when pm_runtime_get_sync() is called, the latter will notice that the runtime PM status of the device is RPM_ACTIVE and it will return right away without waiting for the former to complete. In fact, it cannot wait for .runtime_idle() to complete because it may be called from that callback (it arguably does not make much sense to do that, but it is not strictly prohibited). Thus in general, whoever is providing a .runtime_idle() callback needs to protect it from running in parallel with whatever code runs after pm_runtime_get_sync(). [Note that .runtime_idle() will not start after pm_runtime_get_sync() has returned, but it may continue running then if it has started earlier.] One way to address that race condition is to call pm_runtime_barrier() after pm_runtime_get_sync() (not before it, because a nonzero value of the runtime PM usage counter is necessary to prevent runtime PM callbacks from being invoked) to wait for the .runtime_idle() callback to complete should it be running at that point. A suitable place for doing that is in pci_device_remove() which calls pm_runtime_get_sync() before removing the driver, so it may as well call pm_runtime_barrier() subsequently, which will prevent the race in question from occurring, not just in the rtsx_pcr driver, but in any PCI drivers providing .runtime_idle() callbacks.

Additional Descriptions (1)

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: PCI/PM: drena las devoluciones de llamada inactivas en tiempo de ejecución antes de eliminar el controlador. Una condición de ejecución entre la devolución de llamada .runtime_idle() y la devolución de llamada .remove() en el controlador PCI rtsx_pcr conduce a un crash de kernel debido a un error de página no controlado [1]. El problema es que no se espera que rtsx_pci_runtime_idle() se ejecute después de llamar a pm_runtime_get_sync(), pero esto último realmente no garantiza eso. Solo garantiza que las devoluciones de llamada de suspensión y reanudación no se ejecutarán cuando regrese. Sin embargo, si ya se está ejecutando una devolución de llamada .runtime_idle() cuando se llama a pm_runtime_get_sync(), este último notará que el estado de PM en tiempo de ejecución del dispositivo es RPM_ACTIVE y regresará de inmediato sin esperar a que se complete el primero. De hecho, no puede esperar a que se complete .runtime_idle() porque puede ser llamado desde esa devolución de llamada (podría decirse que no tiene mucho sentido hacerlo, pero no está estrictamente prohibido). Por lo tanto, en general, quien proporciona una devolución de llamada .runtime_idle() debe protegerla para que no se ejecute en paralelo con cualquier código que se ejecute después de pm_runtime_get_sync(). [Tenga en cuenta que .runtime_idle() no se iniciará después de que pm_runtime_get_sync() haya regresado, pero puede continuar ejecutándose si comenzó antes.] Una forma de abordar esa condición de ejecución es llamar a pm_runtime_barrier() después de pm_runtime_get_sync() (no antes porque es necesario un valor distinto de cero del contador de uso de PM en tiempo de ejecución para evitar que se invoquen devoluciones de llamada de PM en tiempo de ejecución) para esperar a que se complete la devolución de llamada .runtime_idle() en caso de que se esté ejecutando en ese punto. Un lugar adecuado para hacerlo es pci_device_remove() que llama a pm_runtime_get_sync() antes de eliminar el controlador, por lo que también puede llamar a pm_runtime_barrier() posteriormente, lo que evitará que se produzca la ejecución en cuestión, no sólo en el controlador rtsx_pcr, sino en cualquier controlador PCI que proporcione devoluciones de llamada .runtime_idle().

CVSS Metrics

Base Score: 4.7 (MEDIUM)

CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H

Attack VectorLOCAL
Attack ComplexityHIGH
Privileges RequiredLOW
User InteractionNONE
ScopeUNCHANGED
Confidentiality ImpactNONE
Integrity ImpactNONE
Availability ImpactHIGH

Source: [email protected]

Type: Primary

Exploitability Score: 1.0

Impact Score: 3.6

Weaknesses

Source Type Description
[email protected] Primary
en CWE-362

Affected Products

Vendor Product Version Update Type
linux linux_kernel * <built-in method update of dict object at 0x7fd2dbc19000> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd2dbe0c0c0> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd3843e5cc0> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd369e81c00> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd39c4e22c0> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd36b8fed00> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd2dbc0bcc0> Operating System
linux linux_kernel * <built-in method update of dict object at 0x7fd2a0504240> Operating System
debian debian_linux 10.0 <built-in method update of dict object at 0x7fd30864eec0> Operating System

Affected Configurations

Operator: OR

Vulnerable CPE
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Yes cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*

Operator: OR

Vulnerable CPE
Yes cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*

References