CVE-2026-23287 Overview
A race condition vulnerability has been identified in the Linux kernel's SiFive PLIC (Platform-Level Interrupt Controller) interrupt chip driver. The vulnerability exists in the irqchip/sifive-plic module where improper handling of interrupt completion messages during CPU affinity changes can cause interrupts to become permanently frozen.
The PLIC silently ignores interrupt completion messages for disabled interrupts. While a previous fix attempted to address this by checking irqd_irq_disabled() before sending completion messages, this check is insufficient when CPU affinity settings are modified while an interrupt is still being processed by a hardware thread (hart). This creates a scenario where the enable bit for the handling hart can be zero even though irqd_irq_disabled(d) returns false, leading to frozen interrupts.
Critical Impact
Systems running RISC-V processors with SiFive PLIC can experience complete device freezes when interrupt-heavy operations occur during CPU affinity changes, causing denial of service conditions affecting critical peripherals like UART.
Affected Products
- Linux kernel with SiFive PLIC interrupt controller driver
- RISC-V systems using Platform-Level Interrupt Controller (PLIC)
- Embedded systems and SoCs implementing SiFive PLIC architecture
Discovery Timeline
- 2026-03-25 - CVE-2026-23287 published to NVD
- 2026-03-25 - Last updated in NVD database
Technical Details for CVE-2026-23287
Vulnerability Analysis
The vulnerability stems from a race condition in the SiFive PLIC interrupt handling mechanism. The PLIC specification states that when an interrupt handler completes execution, the system writes the interrupt ID to the claim/complete register. However, the PLIC does not verify whether the completion ID matches the last claimed interrupt for that target. If the completion ID doesn't match an enabled interrupt source for the target, the completion is silently ignored.
A previous fix addressed scenarios where interrupts could be disabled during handling by checking irqd_irq_disabled() and re-enabling the interrupt before sending the completion message. However, this fix does not account for CPU affinity changes that can occur while an interrupt is being processed.
When affinity settings change during interrupt handling, the PLIC enable bit for the currently handling hart can be cleared (set to zero) even while irqd_irq_disabled(d) returns false. This creates a window where completion messages are silently dropped, causing the interrupt to remain in a claimed but never completed state—effectively freezing the interrupt source.
Root Cause
The root cause is an incomplete condition check in the plic_irq_eoi() function. The existing fix relied on irqd_irq_disabled() to determine interrupt state, but this function does not reflect the actual PLIC hardware enable bit state when CPU affinity modifications occur. The mismatch between the software interrupt descriptor state and the hardware PLIC enable register creates the race condition.
Attack Vector
This vulnerability can be triggered through normal system operations when:
- A device generates a high volume of interrupts (e.g., UART during large file transfers)
- Simultaneously, the system or an administrator changes the interrupt's CPU affinity settings
- The timing window allows the affinity change to complete while the PLIC is still processing an interrupt on the original hart
The vulnerability is easily reproducible by dumping a large file to UART while continuously changing the UART interrupt's affinity setting, causing the UART port to freeze almost instantaneously.
The fix involves checking the actual PLIC enable bit instead of relying on irqd_irq_disabled() to accurately determine whether the interrupt completion message will be accepted by the hardware.
Detection Methods for CVE-2026-23287
Indicators of Compromise
- Peripheral devices (UART, network interfaces) becoming unresponsive after periods of high interrupt activity
- System logs showing interrupt handling timeouts or stalls on RISC-V platforms
- Unexpected device freezes coinciding with CPU affinity rebalancing operations
Detection Strategies
- Monitor for frozen interrupt conditions on RISC-V systems using PLIC by checking /proc/interrupts for stuck interrupt counters
- Implement kernel tracing on plic_irq_eoi() to detect completion messages that fail to release interrupt claims
- Review system logs for UART or device timeout errors that correlate with CPU hotplug or irqbalance activity
Monitoring Recommendations
- Enable kernel debugging for interrupt subsystem on affected RISC-V deployments
- Monitor dmesg output for interrupt-related warnings on systems with SiFive PLIC
- Track interrupt affinity changes using ftrace or perf to correlate with device failures
How to Mitigate CVE-2026-23287
Immediate Actions Required
- Apply the kernel patches from the stable kernel branches immediately on affected RISC-V systems
- Temporarily disable automatic interrupt affinity balancing (irqbalance) on production RISC-V systems until patched
- Avoid manual CPU affinity changes on interrupt-heavy devices during critical operations
Patch Information
The Linux kernel development team has released patches to address this vulnerability. The fix modifies the plic_irq_eoi() function to check the actual PLIC hardware enable bit instead of relying on irqd_irq_disabled(). Multiple patch commits have been submitted to the stable kernel branches:
- Kernel Git Commit 1072020685f4
- Kernel Git Commit 1883332bf21f
- Kernel Git Commit 2edbd1733091
- Kernel Git Commit 686eb378a4a5
- Kernel Git Commit 8942fb1a5bc2
- Kernel Git Commit f611791a9271
Workarounds
- Disable irqbalance service on affected RISC-V systems: systemctl stop irqbalance && systemctl disable irqbalance
- Pin critical device interrupts to specific CPUs and prevent affinity changes during high-throughput operations
- For embedded deployments, consider statically assigning interrupt affinities in device tree configurations
# Configuration example
# Disable irqbalance to prevent automatic affinity changes
systemctl stop irqbalance
systemctl disable irqbalance
# Alternatively, exclude specific interrupts from irqbalance
# Add to /etc/sysconfig/irqbalance or /etc/default/irqbalance
IRQBALANCE_BANNED_CPUS="0" # Example: keep interrupts on CPU 0
# For critical UART device, pin interrupt to specific CPU
# Find UART IRQ number
cat /proc/interrupts | grep -i uart
# Set affinity mask (e.g., CPU 0 only)
echo 1 > /proc/irq/<IRQ_NUMBER>/smp_affinity
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

