CVE-2026-89946 in Linux
Summary
by MITRE • 09/16/2026
In the Linux kernel, the following vulnerability has been resolved:
ASoC: cs35l33: drain threaded IRQ before runtime suspend
cs35l33_runtime_suspend() currently switches the codec into regcache_cache_only(true) and powers it down without first quiescing the threaded IRQ registered by devm_request_threaded_irq(). That leaves a window where cs35l33_irq_thread() can still run after suspend has closed off live register access.
A running system can reach this during runtime PM while the driver still has critical fault IRQs unmasked. If the threaded handler runs in that window, it reads volatile INT_STATUS_1/2 after cache_only has been enabled, ignores the regmap_read() failures, and can still drive the AMP_SHORT_RLS, CAL_ERR_RLS, OTE_RLS, and OTW_RLS release paths.
Use disable_irq() before entering cache_only/power-off so any in-flight threaded handler is drained and no new IRQ thread can run during the suspended state. Re-enable the IRQ only after runtime_resume() has restored live register access with regcache_sync(). Since probe only warns if devm_request_threaded_irq() fails, track whether the IRQ was actually installed before disabling or re-enabling it.
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 09/16/2026
The Linux kernel audio subsystem driver for the Cirrus Logic CS35L33 codec contains a race condition vulnerability during runtime power management transitions that can lead to undefined behavior and potential system instability. This issue arises from an improper sequencing of operations when suspending the device, specifically regarding the handling of threaded interrupt requests. The core technical flaw lies in the cs35l33_runtime_suspend function, which currently switches the codec into a register cache-only mode by calling regcache_cache_only with true and subsequently powers down the hardware without first quiescing or draining the threaded IRQ registered via devm_request_threaded_irq. This sequence creates a critical window of vulnerability where the interrupt handler thread cs35l33_irq_thread may continue to execute even after the suspend routine has disabled live register access on the device.
When this race condition is triggered, typically during runtime power management while the driver still has critical fault interrupts unmasked, the threaded handler proceeds to read volatile status registers INT_STATUS_1 and INT_STATUS_2. Because the hardware is effectively powered down or in a state where direct register access fails, these reads return errors which are currently ignored by the code logic. Despite the failure of the underlying I operations, the driver continues to execute release paths for various fault conditions such as AMP_SHORT_RLS, CAL_ERR_RLS, OTE_RLS, and OTW_RLS. Accessing or processing state based on failed register reads can lead to incorrect internal state management within the kernel audio subsystem, potentially causing data corruption or unpredictable behavior in subsequent operations when the device is resumed.
This vulnerability aligns with CWE-362, which describes concurrent execution issues resulting from race conditions where shared resources are accessed without proper synchronization. In this specific context, the shared resource is the hardware register interface and the internal driver state machine governing fault handling. The lack of atomicity between disabling interrupts and entering the low-power state allows a thread to operate on stale or invalid data structures derived from failed I/O operations. This scenario also reflects aspects of CWE-367 regarding time-of-check-time-of-use errors, as the code checks for interrupt conditions but acts upon them after the hardware interface has become inaccessible due to power management actions taken by another part of the same function.
From an operational impact perspective, this race condition can manifest as audio glitches, system hangs, or kernel panics depending on how the invalid state transitions are handled downstream in the ALSA subsystem. While it may not always lead to immediate catastrophic failure, it introduces significant instability into systems relying on runtime power management for battery life optimization. The issue is particularly relevant for mobile and embedded devices where frequent suspend-resume cycles are common during user activity pauses or background tasks.
To mitigate this vulnerability, the driver implementation must be modified to ensure that all in-flight threaded interrupt handlers are drained before entering the cache-only mode. This requires calling disable_irq prior to enabling regcache_cache_only and powering down the device. Furthermore, it is essential to re-enable the IRQ only after runtime_resume has successfully restored live register access through a call to regcache_sync. Additionally, since the probe function currently issues warnings rather than failing on errors from devm_request_threaded_irq, the driver must track whether the interrupt was actually installed before attempting to disable or re-enable it during suspend and resume cycles. This ensures that operations are only performed when valid interrupt contexts exist, preventing null pointer dereferences or invalid state transitions associated with non-existent IRQ threads.
This fix addresses a fundamental concurrency control issue within kernel device drivers and reinforces best practices for handling hardware interrupts during power management states. By ensuring proper serialization of interrupt disabling and register access suspension, the driver maintains data integrity and system stability. The remediation strategy aligns with standard defensive programming techniques recommended in Linux kernel development guidelines to prevent race conditions that exploit timing windows between state changes and asynchronous event handlers.