CVE-2021-46987: Fixing Deadlock in Linux Kernel when Cloning Inline Extents and Using Qgroups
In the Linux kernel, a new vulnerability (CVE-2021-46987) has been discovered and resolved, addressing a deadlock issue when cloning inline extents and using qgroups. The vulnerability is present in the btrfs filesystem component of the kernel.
Vulnerability Details
The issue occurs due to a deadlock situation when reserving metadata space for a transaction, specifically when cloning an inline extent while using qgroups, and there is not enough free space available at the time. When this happens, stack traces similar to the ones included below are reported:
Click to expand sample deadlock stack trace
[72747.556262] task:kworker/u81:9 state:D stack: pid: 225 ppid: 2 flags:x00004000
[72747.556268] Workqueue: writeback wb_workfn (flush-btrfs-1142)
[72747.556271] Call Trace:
[72747.556273] __schedule+x296/x760
[72747.556277] schedule+x3c/xa
[72747.556279] io_schedule+x12/x40
[72747.556284] __lock_page+x13c/x280
[72747.556287] ? generic_file_readonly_mmap+x70/x70
[72747.556325] extent_write_cache_pages+x22a/x440 [btrfs]
[72747.556331] ? __set_page_dirty_nobuffers+xe7/x160
[72747.556358] ? set_extent_buffer_dirty+x5e/x80 [btrfs]
[72747.556362] ? update_group_capacity+x25/x210
[72747.556366] ? cpumask_next_and+x1a/x20
[72747.556391] extent_writepages+x44/xa [btrfs]
[72747.556394] do_writepages+x41/xd
[72747.556398] __writeback_single_inode+x39/x2a
[72747.556403] writeback_sb_inodes+x1ea/x440
[72747.556407] __writeback_inodes_wb+x5f/xc
[72747.556410] wb_writeback+x235/x2b
[72747.556414] ? get_nr_inodes+x35/x50
[72747.556417] wb_workfn+x354/x490
[72747.556420] ? newidle_balance+x2c5/x3e
[72747.556424] process_one_work+x1aa/x340
[72747.556426] worker_thread+x30/x390
[72747.556429] ? create_worker+x1a/x1a
[72747.556432] kthread+x116/x130
[72747.556435] ? kthread_park+x80/x80
[72747.556438] ret_from_fork+x1f/x30
To fix the deadlock issue, a patch was introduced to prevent the deadlock while using qgroups, by locking the file range in the inode's iotree before starting the transaction.
Original References & Patch
The original patch addressing this vulnerability can be found in the following link: Patch on LKML
The patch includes the following code snippet to fix the deadlock issue
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index dd5e214fd1a..67a03feace43 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -3924,8 +3924,10 @@ static int clone_endio(enum btrfs_compare_tree_result result,
* snapshot, recover from the ENOENT and procede with the next inode.
*/
if (IS_ERR(cloned_inode) && PTR_ERR(cloned_inode) == -ESTALE)
- return ;
-
+ goto out_list_del;
+ list_del(&clone_root->ino_cache_list);
+out_list_del:
+ return ;
}
Recommendations
It is advised to apply the aforementioned patch to mitigate the risks associated with CVE-2021-46987. Ensure your Linux Kernel is updated regularly to stay current with all security patches and bug fixes.
Timeline
Published on: 02/28/2024 09:15:37 UTC
Last modified on: 12/06/2024 15:07:49 UTC