CVE-2026-89589
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
11/09/2026
Última modificación:
21/09/2026
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
acpi/apei/ghes: Use raw_spinlock_t for CXL CPER work locks<br />
<br />
The CXL CPER work registration and unregistration helpers acquire<br />
cxl_cper_work_lock and cxl_cper_prot_err_work_lock with a spinlock<br />
guard(), which leaves local interrupts enabled. The corresponding post<br />
paths (cxl_cper_post_event(), cxl_cper_post_prot_err()) execute in hard<br />
IRQ context (they are called from the GHES error notification path) and<br />
acquire the same locks with an irqsave guard().<br />
<br />
If a CPU is holding one of these locks via a spinlock guard() when a GHES<br />
interrupt arrives on the same CPU, the IRQ handler spins on the held lock<br />
waiting for it to release, while the lock holder is preempted by the IRQ.<br />
The result is a deadlock.<br />
<br />
Convert both locks from spinlock_t to raw_spinlock_t and use guard() at<br />
all call sites. On PREEMPT_RT kernels spinlock_t is backed by rt_mutex and<br />
sleeping from hard IRQ context is not permitted; raw_spinlock_t is safe in<br />
both contexts.<br />
<br />
Add WARN_ONCE to both register functions to surface double-registration<br />
bugs at runtime.<br />
<br />
Restructure both unregister functions to clear the global work pointer<br />
under the lock before calling cancel_work_sync(), closing the window<br />
where a CPER interrupt could schedule work on a pointer about to be<br />
freed. Add kfifo_reset() after cancel_work_sync() so stale entries<br />
are not replayed on next module load.<br />
<br />
Both kfifos are single-consumer: only one work_struct is registered at<br />
a time, enforced by the WARN_ONCE guard in the register functions.<br />
kfifo_reset() is safe outside the lock because cancel_work_sync() has<br />
already quiesced the consumer, and no new consumer can register until<br />
the current module exit completes and a fresh module init runs.<br />
<br />
Remove the redundant cancel_work_sync() call from cxl_ras_exit() and<br />
cxl_pci_driver_exit(). The CPER unregister functions now quiesce<br />
the work internally.


