CVE-2026-46061 Overview
CVE-2026-46061 is a deadlock vulnerability in the Linux kernel's JBD2 (Journaling Block Device 2) subsystem. The flaw resides in jbd2_journal_cancel_revoke() and stems from a broken lock ordering between folio locks and buffer locks. The issue affects ext4 filesystems where the block size is smaller than the page size. Under concurrent directory creation and block device writeback, two kernel threads can acquire locks in opposite orders, producing an ABBA deadlock. The Linux kernel maintainers have resolved the vulnerability through upstream patches in the stable kernel tree.
Critical Impact
Concurrent ext4 directory operations and block device writeback can deadlock kernel threads, causing the system or affected filesystem workloads to hang.
Affected Products
- Linux kernel versions containing commit f76d4c28a46a ("fs/jbd2: use sleeping version of __find_get_block()")
- ext4 filesystem deployments where filesystem block size is smaller than the system page size
- Linux distributions shipping the affected JBD2 journaling code prior to the upstream fix
Discovery Timeline
- 2026-05-27 - CVE-2026-46061 published to NVD
- 2026-05-27 - Last updated in NVD database
Technical Details for CVE-2026-46061
Vulnerability Analysis
The deadlock occurs along two converging code paths in the Linux kernel. Thread T1 executes ext4_mkdir(), which calls ext4_init_new_dir() and ext4_append(). This path invokes ext4_getblk() and acquires the buffer lock through lock_buffer(). T1 then proceeds into ext4_journal_get_create_access() and jbd2_journal_cancel_revoke(), where it attempts to acquire a folio lock.
Thread T2 executes sync_blockdev(), which calls blkdev_writepages() and writeback_iter(). This path acquires the folio lock through writeback_get_folio() and then attempts to acquire the buffer lock through block_write_full_folio() and lock_buffer(). Each thread holds a lock that the other requires, producing a classic ABBA deadlock [CWE-833]. The xfstest generic/013 occasionally hangs as a result.
Root Cause
The regression was introduced by commit f76d4c28a46a ("fs/jbd2: use sleeping version of __find_get_block()"). That change replaced __find_get_block() with __find_get_block_nonatomic() inside jbd2_journal_cancel_revoke(). The new helper holds the folio lock instead of i_private_lock. This violated the kernel's established lock ordering, which requires folio locks to be taken before buffer locks.
Attack Vector
This is a concurrency bug exercisable by legitimate filesystem workloads rather than a remote attack vector. Triggering the condition requires concurrent directory creation under ext4 alongside block device writeback on a filesystem whose block size is smaller than the page size. The fix restricts __find_get_block_nonatomic() to cases where the passed buffer_head does not belong to the bdev, eliminating the redundant lookup that caused the lock inversion.
No verified proof-of-concept code is available. See the upstream patches for technical detail: Kernel commit 2b2fee89, Kernel commit 981fcc56, Kernel commit bbd943d6, and Kernel commit dff07cc9.
Detection Methods for CVE-2026-46061
Indicators of Compromise
- Kernel hung task warnings referencing jbd2_journal_cancel_revoke, lock_buffer, or folio_lock in stack traces
- Processes blocked in D (uninterruptible sleep) state during ext4 directory creation combined with block device writeback
- xfstests generic/013 runs that hang on affected kernels
Detection Strategies
- Inspect kernel logs via dmesg and /var/log/messages for INFO: task ... blocked for more than messages naming JBD2 functions
- Enable hung_task_panic or hung_task_timeout_secs tuning to surface stalls in test environments before production deployment
- Audit deployed kernel versions against the fixed commit hashes to identify hosts still running vulnerable JBD2 code
Monitoring Recommendations
- Track filesystem latency and I/O wait metrics on ext4 hosts with sub-page block sizes
- Forward kernel logs and hung task warnings to a centralized log pipeline for correlation across the fleet
- Alert on sustained D-state process counts that exceed baseline on database, mail, or file servers using ext4
How to Mitigate CVE-2026-46061
Immediate Actions Required
- Update affected Linux kernels to a stable release that includes the upstream JBD2 fix
- Identify hosts that use ext4 with mkfs.ext4 -b block sizes smaller than the page size and prioritize them for patching
- Reboot patched systems to load the updated kernel image
Patch Information
The upstream fix restricts __find_get_block_nonatomic() invocation in jbd2_journal_cancel_revoke() to cases where the passed buffer_head does not belong to the block device. When the buffer already matches, the redundant lookup and its folio lock acquisition are skipped, restoring the original lock ordering. Patches are available in the stable tree as commits 2b2fee89, 981fcc56, bbd943d6, and dff07cc9. Apply the vendor-supplied kernel package corresponding to your distribution.
Workarounds
- Use filesystem block sizes equal to the system page size where feasible, since the deadlock requires blocksize < pagesize
- Avoid running sync_blockdev() or block device writeback concurrently with heavy ext4 directory creation workloads on unpatched kernels
- Pin workloads to kernels predating commit f76d4c28a46a if rolling forward to a patched release is not immediately possible
# Verify the running kernel and check for the fix
uname -r
# Inspect kernel logs for JBD2-related hung tasks
dmesg | grep -i -E 'jbd2|hung task|blocked for more than'
# Confirm ext4 block size vs page size on a mounted filesystem
tune2fs -l /dev/sdXY | grep -i 'block size'
getconf PAGE_SIZE
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

