CVE-2021-46987: btrfs: fix deadlock when cloning inline extents and using qgroups

Published Feb 28, 2024
·
Updated

In the Linux kernel, the following vulnerability has been resolved:

btrfs: fix deadlock when cloning inline extents and using qgroups

There are a few exceptional cases where cloning an inline extent needs to copy the inline extent data into a page of the destination inode.

When this happens, we end up starting a transaction while having a dirty page for the destination inode and while having the range locked in the destination's inode iotree too. Because when reserving metadata space for a transaction we may need to flush existing delalloc in case there is not enough free space, we have a mechanism in place to prevent a deadlock, which was introduced in commit 3d45f221ce627d ("btrfs: fix deadlock when cloning inline extent and low on free metadata space").

However when using qgroups, a transaction also reserves metadata qgroup space, which can also result in flushing delalloc in case there is not enough available space at the moment. When this happens we deadlock, since flushing delalloc requires locking the file range in the inode's iotree and the range was already locked at the very beginning of the clone operation, before attempting to start the transaction.

When this issue happens, stack traces like the following are reported:

[72747.556262] task:kworker/u81:9 state:D stack: 0 pid: 225 ppid: 2 flags:0x00004000 [72747.556268] Workqueue: writeback wbworkfn (flush-btrfs-1142) [72747.556271] Call Trace: [72747.556273] schedule+0x296/0x760 [72747.556277] schedule+0x3c/0xa0 [72747.556279] ioschedule+0x12/0x40 [72747.556284] lockpage+0x13c/0x280 [72747.556287] ? genericfilereadonlymmap+0x70/0x70 [72747.556325] extentwritecachepages+0x22a/0x440 [btrfs] [72747.556331] ? setpagedirtynobuffers+0xe7/0x160 [72747.556358] ? setextentbufferdirty+0x5e/0x80 [btrfs] [72747.556362] ? updategroupcapacity+0x25/0x210 [72747.556366] ? cpumasknextand+0x1a/0x20 [72747.556391] extentwritepages+0x44/0xa0 [btrfs] [72747.556394] dowritepages+0x41/0xd0 [72747.556398] writebacksingleinode+0x39/0x2a0 [72747.556403] writebacksbinodes+0x1ea/0x440 [72747.556407] writebackinodeswb+0x5f/0xc0 [72747.556410] wbwriteback+0x235/0x2b0 [72747.556414] ? getnrinodes+0x35/0x50 [72747.556417] wbworkfn+0x354/0x490 [72747.556420] ? newidlebalance+0x2c5/0x3e0 [72747.556424] processonework+0x1aa/0x340 [72747.556426] workerthread+0x30/0x390 [72747.556429] ? createworker+0x1a0/0x1a0 [72747.556432] kthread+0x116/0x130 [72747.556435] ? kthreadpark+0x80/0x80 [72747.556438] retfromfork+0x1f/0x30

[72747.566958] Workqueue: btrfs-flushdelalloc btrfsworkhelper [btrfs] [72747.566961] Call Trace: [72747.566964] schedule+0x296/0x760 [72747.566968] ? finishwait+0x80/0x80 [72747.566970] schedule+0x3c/0xa0 [72747.566995] waitextentbit.constprop.68+0x13b/0x1c0 [btrfs] [72747.566999] ? finishwait+0x80/0x80 [72747.567024] lockextentbits+0x37/0x90 [btrfs] [72747.567047] btrfsinvalidatepage+0x299/0x2c0 [btrfs] [72747.567051] ? findgetpagesrangetag+0x2cd/0x380 [72747.567076] extentwritepage+0x203/0x320 [btrfs] [72747.567102] extentwritecachepages+0x2bb/0x440 [btrfs] [72747.567106] ? updateloadavg+0x7e/0x5f0 [72747.567109] ? enqueueentity+0xf4/0x6f0 [72747.567134] extentwritepages+0x44/0xa0 [btrfs] [72747.567137] ? enqueuetaskfair+0x93/0x6f0 [72747.567140] dowritepages+0x41/0xd0 [72747.567144] filemapfdatawriterange+0xc7/0x100 [72747.567167] btrfsrundelallocwork+0x17/0x40 [btrfs] [72747.567195] btrfsworkhelper+0xc2/0x300 [btrfs] [72747.567200] processonework+0x1aa/0x340 [72747.567202] workerthread+0x30/0x390 [72747.567205] ? createworker+0x1a0/0x1a0 [72747.567208] kthread+0x116/0x130 [72747.567211] ? kthreadpark+0x80/0x80 [72747.567214] retfromfork+0x1f/0x30

[72747.569686] task:fsstress state:D stack: ---truncated---

Affected Software

3 affected components
Linux Linux kernel>=5.9<5.11.22
Linux Linux kernel>=5.12<5.12.5
Linux Linux kernel=5.13-rc1

Event History

Feb 28, 2024
CVE Published
via MITRE·08:13 AM
Data Sourced
via MITRE·08:13 AM
Description
Data Sourced
via NVD·09:15 AM
RemedyDescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2021-46987?

CVE-2021-46987 has a medium severity rating due to the potential for deadlocks in the Linux kernel during the cloning of inline extents.

2

How do I fix CVE-2021-46987?

To mitigate CVE-2021-46987, upgrade to a patched version of the Linux kernel that addresses the deadlock issue.

3

Which versions of the Linux kernel are affected by CVE-2021-46987?

CVE-2021-46987 affects Linux kernel versions from 5.9 to 5.11.22 and 5.12 to 5.12.5, including 5.13-rc1.

4

What component of the Linux kernel is involved in CVE-2021-46987?

CVE-2021-46987 involves the btrfs file system, specifically the cloning of inline extents.

5

Is there a workaround for CVE-2021-46987?

There are no specific workarounds for CVE-2021-46987; upgrading to a fixed version is the recommended action.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203