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&#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->i_ea<br />
3. Then, following three processes running like this:<br />
<br />
PA PB<br />
echo 2 > /proc/sys/vm/drop_caches<br />
shrink_slab<br />
prune_dcache_sb<br />
// i_reg is added into lru, lru->i_ea->i_reg<br />
prune_icache_sb<br />
list_lru_walk_one<br />
inode_lru_isolate<br />
i_ea->i_state |= I_FREEING // set inode state<br />
inode_lru_isolate<br />
__iget(i_reg)<br />
spin_unlock(&i_reg->i_lock)<br />
spin_unlock(lru_lock)<br />
rm file A<br />
i_reg->nlink = 0<br />
iput(i_reg) // i_reg->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->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(&i_ea->i_state)<br />
<br />
Case 2: In deleted inode writing function ubifs_jnl_write_inode(), file<br />
deleting process holds BASEHD&#39;s wbuf->io_mutex while getting the<br />
xattr inode, which could race with inode reclaiming process(The<br />
reclaiming process could try locking BASEHD&#39;s wbuf->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->ixa<br />
3. Then, following three processes running like this:<br />
<br />
PA PB PC<br />
echo 2 > /proc/sys/vm/drop_caches<br />
shrink_slab<br />
prune_dcache_sb<br />
// ib and ia are added into lru, lru->ixa->ib->ia<br />
prune_icache_sb<br />
list_lru_walk_one<br />
inode_lru_isolate<br />
ixa->i_state |= I_FREEING // set inode state<br />
inode_lru_isolate<br />
__iget(ib)<br />
spin_unlock(&ib->i_lock)<br />
spin_unlock(lru_lock)<br />
rm file B<br />
ib->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->io_mutex<br />
ubifs_iget(ixa->i_ino)<br />
iget_locked<br />
find_inode_fast<br />
__wait_on_freeing_inode(ixa)<br />
| iput(ib) // ib->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(&ixa->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---
Impact
Base Score 3.x
4.70
Severity 3.x
MEDIUM
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:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/03880af02a78bc9a98b5a581f529cf709c88a9b8
- https://git.kernel.org/stable/c/2a0629834cd82f05d424bbc193374f9a43d1f87d
- https://git.kernel.org/stable/c/3525ad25240dfdd8c78f3470911ed10aa727aa72
- https://git.kernel.org/stable/c/437741eba63bf4e437e2beb5583f8633556a2b98
- https://git.kernel.org/stable/c/9063ab49c11e9518a3f2352434bb276cc8134c5f
- https://git.kernel.org/stable/c/b9bda5f6012dd00372f3a06a82ed8971a4c57c32
- https://git.kernel.org/stable/c/cda54ec82c0f9d05393242b20b13f69b083f7e88
- https://lists.debian.org/debian-lts-announce/2024/10/msg00003.html
- https://lists.debian.org/debian-lts-announce/2025/01/msg00001.html



