CVE-2024-49868: btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
In the Linux kernel, the following vulnerability has been resolved:
btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
[BUG] Syzbot reported a NULL pointer dereference with the following crash:
FAULTINJECTION: forcing a failure. starttransaction+0x830/0x1670 fs/btrfs/transaction.c:676 preparetorelocate+0x31f/0x4c0 fs/btrfs/relocation.c:3642 relocateblockgroup+0x169/0xd20 fs/btrfs/relocation.c:3678 ... BTRFS info (device loop0): balance: ended with status: -12 Oops: general protection fault, probably for non-canonical address 0xdffffc00000000cc: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000660-0x0000000000000667] RIP: 0010:btrfsupdaterelocroot+0x362/0xa80 fs/btrfs/relocation.c:926 Call Trace: <TASK> commitfsroots+0x2ee/0x720 fs/btrfs/transaction.c:1496 btrfscommittransaction+0xfaf/0x3740 fs/btrfs/transaction.c:2430 delbalanceitem fs/btrfs/volumes.c:3678 [inline] resetbalancestate+0x25e/0x3c0 fs/btrfs/volumes.c:3742 btrfsbalance+0xead/0x10c0 fs/btrfs/volumes.c:4574 btrfsioctlbalance+0x493/0x7c0 fs/btrfs/ioctl.c:3673 vfsioctl fs/ioctl.c:51 [inline] dosysioctl fs/ioctl.c:907 [inline] sesysioctl+0xf9/0x170 fs/ioctl.c:893 dosyscallx64 arch/x86/entry/common.c:52 [inline] dosyscall64+0xf3/0x230 arch/x86/entry/common.c:83 entrySYSCALL64afterhwframe+0x77/0x7f
[CAUSE] The allocation failure happens at the starttransaction() inside preparetorelocate(), and during the error handling we call unsetreloccontrol(), which makes fsinfo->balancectl to be NULL.
Then we continue the error path cleanup in btrfsbalance() by calling resetbalancestate() which will call delbalanceitem() to fully delete the balance item in the root tree.
However during the small window between setreloccontrl() and unsetreloccontrol(), we can have a subvolume tree update and created a relocroot for that subvolume.
Then we go into the final btrfscommittransaction() of delbalanceitem(), and into btrfsupdaterelocroot() inside commitfsroots().
That function checks if fsinfo->relocctl is in the mergereloctree stage, but since fsinfo->relocctl is NULL, it results a NULL pointer dereference.
[FIX] Just add extra check on fsinfo->relocctl inside btrfsupdaterelocroot(), before checking fsinfo->relocctl->mergereloctree.
That DEADRELOCTREE handling is to prevent further modification to the reloc tree during merge stage, but since there is no relocctl at all, we do not need to bother that.
Other sources
This CVE was automatically created from a reference found in an email or other text. If you are reading this, then this CVE entry is probably erroneous, since this text should be replaced by the official CVE description automatically.
— Launchpad
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2024-49868?
CVE-2024-49868 is categorized as a high-severity vulnerability.
How do I fix CVE-2024-49868?
To fix CVE-2024-49868, upgrade to a non-vulnerable version of the Linux kernel as specified in the security patch.
Which versions of the Linux kernel are affected by CVE-2024-49868?
CVE-2024-49868 affects Linux kernel versions from 5.11 up to 6.10.14.
What type of vulnerability is CVE-2024-49868?
CVE-2024-49868 is a NULL pointer dereference vulnerability in the Linux kernel.
What can happen if CVE-2024-49868 is exploited?
Exploitation of CVE-2024-49868 can lead to a system crash or denial of service.