45 lines
5.4 KiB
JSON
Raw Normal View History

{
"id": "CVE-2024-45003",
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"published": "2024-09-04T20:15:08.823",
"lastModified": "2024-09-04T20:15:08.823",
"vulnStatus": "Received",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nvfs: Don't evict inode under the inode lru traversing context\n\nThe inode reclaiming process(See function prune_icache_sb) collects all\nreclaimable inodes and mark them with I_FREEING flag at first, at that\ntime, other processes will be stuck if they try getting these inodes\n(See function find_inode_fast), then the reclaiming process destroy the\ninodes by function dispose_list(). Some filesystems(eg. ext4 with\nea_inode feature, ubifs with xattr) may do inode lookup in the inode\nevicting callback function, if the inode lookup is operated under the\ninode lru traversing context, deadlock problems may happen.\n\nCase 1: In function ext4_evict_inode(), the ea inode lookup could happen\n if ea_inode feature is enabled, the lookup process will be stuck\n\tunder the evicting context like this:\n\n 1. File A has inode i_reg and an ea inode i_ea\n 2. getfattr(A, xattr_buf) // i_ea is added into lru // lru->i_ea\n 3. Then, following three processes running like this:\n\n PA PB\n echo 2 > /proc/sys/vm/drop_caches\n shrink_slab\n prune_dcache_sb\n // i_reg is added into lru, lru->i_ea->i_reg\n prune_icache_sb\n list_lru_walk_one\n inode_lru_isolate\n i_ea->i_state |= I_FREEING // set inode state\n inode_lru_isolate\n __iget(i_reg)\n spin_unlock(&i_reg->i_lock)\n spin_unlock(lru_lock)\n rm file A\n i_reg->nlink = 0\n iput(i_reg) // i_reg->nlink is 0, do evict\n ext4_evict_inode\n ext4_xattr_delete_inode\n ext4_xattr_inode_dec_ref_all\n ext4_xattr_inode_iget\n ext4_iget(i_ea->i_ino)\n iget_locked\n find_inode_fast\n __wait_on_freeing_inode(i_ea) ----\u2192 AA deadlock\n dispose_list // cannot be executed by prune_icache_sb\n wake_up_bit(&i_ea->i_state)\n\nCase 2: In deleted inode writing function ubifs_jnl_write_inode(), file\n deleting process holds BASEHD's wbuf->io_mutex while getting the\n\txattr inode, which could race with inode reclaiming process(The\n reclaiming process could try locking BASEHD's wbuf->io_mutex in\n\tinode evicting function), then an ABBA deadlock problem would\n\thappen as following:\n\n 1. File A has inode ia and a xattr(with inode ixa), regular file B has\n inode ib and a xattr.\n 2. getfattr(A, xattr_buf) // ixa is added into lru // lru->ixa\n 3. Then, following three processes running like this:\n\n PA PB PC\n echo 2 > /proc/sys/vm/drop_caches\n shrink_slab\n prune_dcache_sb\n // ib and ia are added into lru, lru->ixa->ib->ia\n prune_icache_sb\n list_lru_walk_one\n inode_lru_isolate\n ixa->i_state |= I_FREEING // set inode state\n inode_lru_isolate\n __iget(ib)\n spin_unlock(&ib->i_lock)\n spin_unlock(lru_lock)\n rm file B\n ib->nlink = 0\n rm file A\n iput(ia)\n ubifs_evict_inode(ia)\n ubifs_jnl_delete_inode(ia)\n ubifs_jnl_write_inode(ia)\n make_reservation(BASEHD) // Lock wbuf->io_mutex\n ubifs_iget(ixa->i_ino)\n iget_locked\n find_inode_fast\n __wait_on_freeing_inode(ixa)\n | iput(ib) // ib->nlink is 0, do evict\n | ubifs_evict_inode\n | ubifs_jnl_delete_inode(ib)\n \u2193 ubifs_jnl_write_inode\n ABBA deadlock \u2190-----make_reservation(BASEHD)\n dispose_list // cannot be executed by prune_icache_sb\n wake_up_bit(&ixa->i_state)\n\nFix the possible deadlock by using new inode state flag I_LRU_ISOLATING\nto pin the inode in memory while inode_lr
}
],
"metrics": {},
"references": [
{
"url": "https://git.kernel.org/stable/c/03880af02a78bc9a98b5a581f529cf709c88a9b8",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/2a0629834cd82f05d424bbc193374f9a43d1f87d",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/3525ad25240dfdd8c78f3470911ed10aa727aa72",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/437741eba63bf4e437e2beb5583f8633556a2b98",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/9063ab49c11e9518a3f2352434bb276cc8134c5f",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/b9bda5f6012dd00372f3a06a82ed8971a4c57c32",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/cda54ec82c0f9d05393242b20b13f69b083f7e88",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}
]
}