CVE-2022-49850 in Linux
Summary
by MITRE • 05/01/2025
In the Linux kernel, the following vulnerability has been resolved:
nilfs2: fix deadlock in nilfs_count_free_blocks()
A semaphore deadlock can occur if nilfs_get_block() detects metadata corruption while locating data blocks and a superblock writeback occurs at the same time:
task 1 task 2 ------ ------ * A file operation * nilfs_truncate() nilfs_get_block() down_read(rwsem A) <-- nilfs_bmap_lookup_contig() ... generic_shutdown_super() nilfs_put_super() * Prepare to write superblock * down_write(rwsem B) <-- nilfs_cleanup_super() * Detect b-tree corruption * nilfs_set_log_cursor() nilfs_bmap_convert_error() nilfs_count_free_blocks() __nilfs_error() down_read(rwsem A) <-- nilfs_set_error() down_write(rwsem B) <--
*** DEADLOCK ***
Here, nilfs_get_block() readlocks rwsem A (= NILFS_MDT(dat_inode)->mi_sem) and then calls nilfs_bmap_lookup_contig(), but if it fails due to metadata corruption, __nilfs_error() is called from nilfs_bmap_convert_error() inside the lock section.
Since __nilfs_error() calls nilfs_set_error() unless the filesystem is read-only and nilfs_set_error() attempts to writelock rwsem B (= nilfs->ns_sem) to write back superblock exclusively, hierarchical lock acquisition occurs in the order rwsem A -> rwsem B.
Now, if another task starts updating the superblock, it may writelock rwsem B during the lock sequence above, and can deadlock trying to readlock rwsem A in nilfs_count_free_blocks().
However, there is actually no need to take rwsem A in nilfs_count_free_blocks() because it, within the lock section, only reads a single integer data on a shared struct with nilfs_sufile_get_ncleansegs(). This has been the case after commit aa474a220180 ("nilfs2: add local variable to cache the number of clean segments"), that is, even before this bug was introduced.
So, this resolves the deadlock problem by just not taking the semaphore in nilfs_count_free_blocks().
If you want to get the best quality for vulnerability data then you always have to consider VulDB.
Analysis
by VulDB Data Team • 05/01/2025
The vulnerability described in CVE-2022-49850 represents a critical semaphore deadlock condition within the Linux kernel's nilfs2 filesystem implementation. This issue manifests as a circular dependency between two read-write semaphores that creates an unresolvable deadlock state during concurrent filesystem operations. The flaw specifically occurs in the nilfs_count_free_blocks() function where improper lock ordering leads to system-wide blocking conditions that can severely impact system stability and availability.
The technical root cause stems from improper lock acquisition ordering within the filesystem's metadata handling mechanisms. When nilfs_get_block() detects metadata corruption during block location operations, it attempts to acquire read lock on rwsem A which protects the metadata data structures. However, the error handling path subsequently calls __nilfs_error() and nilfs_set_error() functions that attempt to acquire write lock on rwsem B to perform superblock writeback operations. This creates a hierarchical lock dependency where rwsem A is acquired before rwsem B, but under concurrent conditions, another task may acquire rwsem B first, then attempt to acquire rwsem A, resulting in the classic deadlock scenario.
The operational impact of this vulnerability extends beyond simple system freezing, as it represents a fundamental race condition that can compromise the entire filesystem's integrity. According to CWE-362, this vulnerability exemplifies a concurrent execution condition where improper synchronization leads to system instability. The deadlock occurs specifically during superblock writeback operations when the filesystem attempts to clean up corrupted metadata structures while simultaneously handling concurrent filesystem operations. This scenario can lead to complete system hang conditions where no further filesystem operations can proceed until manual intervention occurs.
The mitigation strategy implemented in this fix directly addresses the lock ordering issue by eliminating unnecessary semaphore acquisition in the nilfs_count_free_blocks() function. This approach aligns with ATT&CK technique T1484.001 which focuses on privilege escalation through race conditions and improper access control. The solution recognizes that the function does not actually require the read lock since it only accesses cached integer data from shared structures, specifically through nilfs_sufile_get_ncleansegs() calls that do not modify protected data. This optimization not only resolves the deadlock but also improves overall filesystem performance by reducing unnecessary lock contention. The fix demonstrates proper lock ordering principles and follows the kernel's established patterns for avoiding hierarchical lock dependencies. The resolution is particularly significant as it addresses a condition that could persist even after the problematic commit aa474a220180, which had already introduced caching mechanisms that made the semaphore acquisition unnecessary for the function's actual operation.