CVE-2026-92503: ext4: fix ABBA deadlock in ext4_xattr_inode_cache_find()
In the Linux kernel, the following vulnerability has been resolved:
ext4: fix ABBA deadlock in ext4xattrinodecachefind()
Syzbot/stress-ng reported an ABBA deadlock in ext4 when exercising concurrent xattr workloads (using the eainode mount/format option).
The deadlock occurs between the running transaction and the eviction thread: - Task 1 (stress-ng): Holds a reference to a shared mbcacheentry (ce) and calls ext4xattrinodecachefind() -> ext4iget() to retrieve the corresponding EA inode. Since the EA inode is currently being evicted, ext4iget() blocks in waitonfreeinginode() waiting for eviction to complete. - Task 2 (eviction thread): Currently evicting the same EA inode in ext4evicteainode(). It calls mbcacheentrywaitunused(oe) which blocks waiting for Task 1 to release the reference to the mbcacheentry.
To break this deadlock, implement a new ext4iget() configuration flag named EXT4IGETNOWAIT. When set, perform a non-blocking lookup of the inode via VFS's findinodenowait() API.
If the inode is currently being evicted (marked with IFREEING or IWILLFREE) or created (ICREATING), or if it is not present in the VFS inode cache (cache miss), simply skip it (returning -ENOENT) rather than waiting for eviction/creation to complete, breaking the ABBA cycle.
Since we return -ENOENT immediately on a cache miss, we never attempt to allocate a new inode or call igetlocked(), completely eliminating any TOCTOU race window.
If the returned inode is INEW, wait for its initialization to clear via waitonnewinode(). If initialization fails and the inode is unhashed during waitonnewinode() waking up (e.g., due to an I/O read error in another thread), safely drop the reference and return -ENOENT. This unhashed check is executed unconditionally on all cache-hit pathways to properly handle concurrent initialization failures.
Finally, standard validation checks (including isbadinode, EXT4EAINODEFL, fileacl, and xattr flags) are executed as normal inside checkigotinode() to fully guarantee VFS-layer safety.
In ext4xattrinodecachefind(), invoke ext4iget() with the new EXT4IGETNOWAIT flag to perform the non-blocking cache search.
Affected Software
Event History
Frequently Asked Questions
Which systems are exposed to this deadlock?
The reported condition involves ext4 filesystems using the ea_inode mount or format option while handling concurrent extended-attribute workloads. It requires contention between xattr lookup activity and eviction of the same EA inode.
What runtime evidence would indicate this condition is occurring?
One task can be blocked in ext4_iget() through __wait_on_freeing_inode() while waiting for an EA inode eviction to finish. At the same time, the eviction thread can be blocked in mb_cache_entry_wait_unused() waiting for the first task to release its shared mbcache entry reference.
How does the fix avoid the deadlock?
The fix adds EXT4_IGET_NOWAIT, causing the affected lookup to use a non-blocking VFS inode lookup. If the inode is being created or evicted, or is absent from the inode cache, the lookup does not wait for it.