CVE-2023-52896

Severity CVSS v4.0:
Pending analysis
Type:
CWE-476 NULL Pointer Dereference
Publication date:
21/08/2024
Last modified:
11/09/2024

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> btrfs: fix race between quota rescan and disable leading to NULL pointer deref<br /> <br /> If we have one task trying to start the quota rescan worker while another<br /> one is trying to disable quotas, we can end up hitting a race that results<br /> in the quota rescan worker doing a NULL pointer dereference. The steps for<br /> this are the following:<br /> <br /> 1) Quotas are enabled;<br /> <br /> 2) Task A calls the quota rescan ioctl and enters btrfs_qgroup_rescan().<br /> It calls qgroup_rescan_init() which returns 0 (success) and then joins a<br /> transaction and commits it;<br /> <br /> 3) Task B calls the quota disable ioctl and enters btrfs_quota_disable().<br /> It clears the bit BTRFS_FS_QUOTA_ENABLED from fs_info-&gt;flags and calls<br /> btrfs_qgroup_wait_for_completion(), which returns immediately since the<br /> rescan worker is not yet running.<br /> Then it starts a transaction and locks fs_info-&gt;qgroup_ioctl_lock;<br /> <br /> 4) Task A queues the rescan worker, by calling btrfs_queue_work();<br /> <br /> 5) The rescan worker starts, and calls rescan_should_stop() at the start<br /> of its while loop, which results in 0 iterations of the loop, since<br /> the flag BTRFS_FS_QUOTA_ENABLED was cleared from fs_info-&gt;flags by<br /> task B at step 3);<br /> <br /> 6) Task B sets fs_info-&gt;quota_root to NULL;<br /> <br /> 7) The rescan worker tries to start a transaction and uses<br /> fs_info-&gt;quota_root as the root argument for btrfs_start_transaction().<br /> This results in a NULL pointer dereference down the call chain of<br /> btrfs_start_transaction(). The stack trace is something like the one<br /> reported in Link tag below:<br /> <br /> general protection fault, probably for non-canonical address 0xdffffc0000000041: 0000 [#1] PREEMPT SMP KASAN<br /> KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f]<br /> CPU: 1 PID: 34 Comm: kworker/u4:2 Not tainted 6.1.0-syzkaller-13872-gb6bb9676f216 #0<br /> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022<br /> Workqueue: btrfs-qgroup-rescan btrfs_work_helper<br /> RIP: 0010:start_transaction+0x48/0x10f0 fs/btrfs/transaction.c:564<br /> Code: 48 89 fb 48 (...)<br /> RSP: 0018:ffffc90000ab7ab0 EFLAGS: 00010206<br /> RAX: 0000000000000041 RBX: 0000000000000208 RCX: ffff88801779ba80<br /> RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000<br /> RBP: dffffc0000000000 R08: 0000000000000001 R09: fffff52000156f5d<br /> R10: fffff52000156f5d R11: 1ffff92000156f5c R12: 0000000000000000<br /> R13: 0000000000000001 R14: 0000000000000001 R15: 0000000000000003<br /> FS: 0000000000000000(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000<br /> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br /> CR2: 00007f2bea75b718 CR3: 000000001d0cc000 CR4: 00000000003506e0<br /> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000<br /> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400<br /> Call Trace:<br /> <br /> btrfs_qgroup_rescan_worker+0x3bb/0x6a0 fs/btrfs/qgroup.c:3402<br /> btrfs_work_helper+0x312/0x850 fs/btrfs/async-thread.c:280<br /> process_one_work+0x877/0xdb0 kernel/workqueue.c:2289<br /> worker_thread+0xb14/0x1330 kernel/workqueue.c:2436<br /> kthread+0x266/0x300 kernel/kthread.c:376<br /> ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308<br /> <br /> Modules linked in:<br /> <br /> So fix this by having the rescan worker function not attempt to start a<br /> transaction if it didn&amp;#39;t do any rescan work.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.4.178 (including) 5.4.230 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.10.99 (including) 5.10.165 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.15.22 (including) 5.15.90 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16.8 (excluding) 5.17 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.17 (including) 6.1.8 (excluding)
cpe:2.3:o:linux:linux_kernel:6.2:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.2:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.2:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.2:rc4:*:*:*:*:*:*