CVE-2026-89566 Overview
CVE-2026-89566 affects the Linux kernel's journaling block device layer (jbd2), which underpins ext4 filesystem journaling. The flaw exists in journal_shrink_one_cp_list(), where the busy-buffer skip path bypasses the need_resched() check at the end of the loop body. Under memory pressure, the shrinker can traverse large checkpoint lists while holding journal->j_list_lock, blocking other CPUs and producing soft lockups or RCU stalls. The Linux kernel maintainers resolved the issue by routing the busy-buffer path through the reschedule check, restoring parity with the clean-buffer path.
Critical Impact
A local workload that pressures the checkpoint shrinker can trigger extended lock hold times on j_list_lock, causing soft lockups, RCU stalls, and system-wide unresponsiveness on affected kernels.
Affected Products
- Linux kernel — fs/jbd2 journaling subsystem
- Distributions shipping affected mainline and stable kernel branches prior to the fix
- Systems using ext4 or other filesystems that rely on jbd2 checkpointing
Discovery Timeline
- 2026-09-11 - CVE-2026-89566 published to the National Vulnerability Database
- 2026-09-11 - Last updated in NVD database
Technical Details for CVE-2026-89566
Vulnerability Analysis
The jbd2 subsystem manages transaction journaling for ext4 and related filesystems. Its checkpoint shrinker walks per-journal checkpoint transaction lists to free buffers when the kernel is under memory pressure. The function journal_shrink_one_cp_list() holds journal->j_list_lock while iterating those lists.
When invoked with the JBD2_SHRINK_BUSY_SKIP flag, the shrinker skips buffers that are currently busy. The continue statement on that skip path jumps past the loop's tail, which contains the need_resched() cooperative preemption check. As a result, a checkpoint list populated primarily with busy buffers is walked in its entirety without yielding, even when the scheduler has requested a reschedule.
On systems with large journals and sustained memory pressure, this behavior extends the time j_list_lock is held. Other CPUs contending for the lock spin, and the kernel's soft lockup detector or RCU stall detector may fire, degrading availability.
Root Cause
The root cause is a missed cooperative scheduling point on a continue-based control-flow branch. The clean-buffer path already reaches need_resched() at the bottom of the loop, but the busy-buffer skip path shortcuts around it. This is a kernel-side denial-of-service condition rather than a memory-safety flaw, and no CWE was assigned in the source advisory.
Attack Vector
Exploitation requires local activity that generates a large checkpoint list of busy buffers while the kernel is under memory pressure. Workloads producing sustained ext4 write traffic combined with reclaim can reach the vulnerable path. No specific privilege beyond local filesystem I/O is required to trigger the condition; the impact is availability, not confidentiality or integrity.
No public proof-of-concept exploit is referenced in the advisory. The EPSS probability at publication is 0.2%, indicating a low likelihood of opportunistic exploitation attempts. See the upstream fixes in Kernel Git Commit f9182a8 and Kernel Git Commit f83c232 for the precise code change.
Detection Methods for CVE-2026-89566
Indicators of Compromise
- Kernel log entries reporting soft lockup - CPU#N stuck for Ns! with call stacks referencing journal_shrink_one_cp_list or jbd2_journal_shrink_checkpoint_list.
- RCU stall warnings (rcu: INFO: rcu_sched self-detected stall) implicating jbd2 shrinker frames.
- Prolonged contention on j_list_lock visible in perf lock or lockstat output during memory-pressure events.
Detection Strategies
- Monitor dmesg and /var/log/messages for soft lockup and RCU stall messages that correlate with high ext4 write activity and low free memory.
- Use perf record -g sampling on affected hosts to capture stacks pointing to journal_shrink_one_cp_list during shrinker invocations.
- Correlate node-level availability drops with memory reclaim pressure metrics from vmstat and /proc/pressure/memory.
Monitoring Recommendations
- Ingest kernel logs and PSI (Pressure Stall Information) metrics into a centralized log platform and alert on repeated soft lockup or RCU stall events.
- Track kernel package versions across the fleet to identify hosts still running pre-fix jbd2 code.
- Baseline normal shrinker latency and alert on outliers during batch or backup windows.
How to Mitigate CVE-2026-89566
Immediate Actions Required
- Inventory hosts running kernels that predate the upstream jbd2 fixes and prioritize systems with heavy ext4 write workloads.
- Apply vendor-supplied kernel updates that incorporate the upstream patches and schedule a reboot into the fixed kernel.
- Where patching is delayed, reduce sustained memory pressure and journal size on high-risk hosts to lower the probability of triggering the condition.
Patch Information
The fix routes the busy-buffer skip path through the existing need_resched() check, allowing the shrinker to drop j_list_lock and yield promptly. The change does not alter which checkpoint buffers are eligible for removal. Upstream commits are available at Kernel Git Commit 595cac7, Kernel Git Commit f213e12, Kernel Git Commit f83c232, and Kernel Git Commit f9182a8. Consult your Linux distribution's security tracker for backported package builds.
Workarounds
- No supported code-level workaround exists; the missed reschedule is on a hot path in journal_shrink_one_cp_list().
- Reduce exposure by tuning vm.dirty_ratio and vm.dirty_background_ratio to smooth writeback and limit checkpoint list growth.
- Increase available memory or lower workload concurrency on affected hosts to reduce shrinker invocations under pressure.
# Verify running kernel version and check for the fixed jbd2 commits
uname -r
# Inspect kernel logs for jbd2 shrinker soft lockups or RCU stalls
dmesg -T | grep -Ei 'soft lockup|rcu.*stall|jbd2|journal_shrink_one_cp_list'
# Reduce dirty page thresholds to limit checkpoint list growth (example values)
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=10
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.