CVE-2024-45003

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
04/09/2024
Last modified:
03/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> vfs: Don&amp;#39;t evict inode under the inode lru traversing context<br /> <br /> The inode reclaiming process(See function prune_icache_sb) collects all<br /> reclaimable inodes and mark them with I_FREEING flag at first, at that<br /> time, other processes will be stuck if they try getting these inodes<br /> (See function find_inode_fast), then the reclaiming process destroy the<br /> inodes by function dispose_list(). Some filesystems(eg. ext4 with<br /> ea_inode feature, ubifs with xattr) may do inode lookup in the inode<br /> evicting callback function, if the inode lookup is operated under the<br /> inode lru traversing context, deadlock problems may happen.<br /> <br /> Case 1: In function ext4_evict_inode(), the ea inode lookup could happen<br /> if ea_inode feature is enabled, the lookup process will be stuck<br /> under the evicting context like this:<br /> <br /> 1. File A has inode i_reg and an ea inode i_ea<br /> 2. getfattr(A, xattr_buf) // i_ea is added into lru // lru-&gt;i_ea<br /> 3. Then, following three processes running like this:<br /> <br /> PA PB<br /> echo 2 &gt; /proc/sys/vm/drop_caches<br /> shrink_slab<br /> prune_dcache_sb<br /> // i_reg is added into lru, lru-&gt;i_ea-&gt;i_reg<br /> prune_icache_sb<br /> list_lru_walk_one<br /> inode_lru_isolate<br /> i_ea-&gt;i_state |= I_FREEING // set inode state<br /> inode_lru_isolate<br /> __iget(i_reg)<br /> spin_unlock(&amp;i_reg-&gt;i_lock)<br /> spin_unlock(lru_lock)<br /> rm file A<br /> i_reg-&gt;nlink = 0<br /> iput(i_reg) // i_reg-&gt;nlink is 0, do evict<br /> ext4_evict_inode<br /> ext4_xattr_delete_inode<br /> ext4_xattr_inode_dec_ref_all<br /> ext4_xattr_inode_iget<br /> ext4_iget(i_ea-&gt;i_ino)<br /> iget_locked<br /> find_inode_fast<br /> __wait_on_freeing_inode(i_ea) ----→ AA deadlock<br /> dispose_list // cannot be executed by prune_icache_sb<br /> wake_up_bit(&amp;i_ea-&gt;i_state)<br /> <br /> Case 2: In deleted inode writing function ubifs_jnl_write_inode(), file<br /> deleting process holds BASEHD&amp;#39;s wbuf-&gt;io_mutex while getting the<br /> xattr inode, which could race with inode reclaiming process(The<br /> reclaiming process could try locking BASEHD&amp;#39;s wbuf-&gt;io_mutex in<br /> inode evicting function), then an ABBA deadlock problem would<br /> happen as following:<br /> <br /> 1. File A has inode ia and a xattr(with inode ixa), regular file B has<br /> inode ib and a xattr.<br /> 2. getfattr(A, xattr_buf) // ixa is added into lru // lru-&gt;ixa<br /> 3. Then, following three processes running like this:<br /> <br /> PA PB PC<br /> echo 2 &gt; /proc/sys/vm/drop_caches<br /> shrink_slab<br /> prune_dcache_sb<br /> // ib and ia are added into lru, lru-&gt;ixa-&gt;ib-&gt;ia<br /> prune_icache_sb<br /> list_lru_walk_one<br /> inode_lru_isolate<br /> ixa-&gt;i_state |= I_FREEING // set inode state<br /> inode_lru_isolate<br /> __iget(ib)<br /> spin_unlock(&amp;ib-&gt;i_lock)<br /> spin_unlock(lru_lock)<br /> rm file B<br /> ib-&gt;nlink = 0<br /> rm file A<br /> iput(ia)<br /> ubifs_evict_inode(ia)<br /> ubifs_jnl_delete_inode(ia)<br /> ubifs_jnl_write_inode(ia)<br /> make_reservation(BASEHD) // Lock wbuf-&gt;io_mutex<br /> ubifs_iget(ixa-&gt;i_ino)<br /> iget_locked<br /> find_inode_fast<br /> __wait_on_freeing_inode(ixa)<br /> | iput(ib) // ib-&gt;nlink is 0, do evict<br /> | ubifs_evict_inode<br /> | ubifs_jnl_delete_inode(ib)<br /> ↓ ubifs_jnl_write_inode<br /> ABBA deadlock ←-----make_reservation(BASEHD)<br /> dispose_list // cannot be executed by prune_icache_sb<br /> wake_up_bit(&amp;ixa-&gt;i_state)<br /> <br /> Fix the possible deadlock by using new inode state flag I_LRU_ISOLATING<br /> to pin the inode in memory while inode_lru_isolate(<br /> ---truncated---

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.13 (including) 5.4.283 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.5 (including) 5.10.225 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11 (including) 5.15.166 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 6.1.107 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (including) 6.6.48 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (including) 6.10.7 (excluding)
cpe:2.3:o:linux:linux_kernel:6.11:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.11:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.11:rc3:*:*:*:*:*:*