CVE-2024-49868

Source
https://nvd.nist.gov/vuln/detail/CVE-2024-49868
Import Source
https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2024-49868.json
JSON Data
https://api.test.osv.dev/v1/vulns/CVE-2024-49868
Downstream
Related
Published
2024-10-21T18:15:06Z
Modified
2025-08-09T20:01:26Z
Severity
  • 5.5 (Medium) CVSS_V3 - CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H CVSS Calculator
Summary
[none]
Details

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 entrySYSCALL64after_hwframe+0x77/0x7f

[CAUSE] The allocation failure happens at the starttransaction() inside preparetorelocate(), and during the error handling we call unsetreloccontrol(), which makes fsinfo->balance_ctl to be NULL.

Then we continue the error path cleanup in btrfsbalance() by calling resetbalancestate() which will call delbalance_item() 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 reloc_root for that subvolume.

Then we go into the final btrfscommittransaction() of delbalanceitem(), and into btrfsupdaterelocroot() inside commitfs_roots().

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->mergereloc_tree.

That DEADRELOCTREE handling is to prevent further modification to the reloc tree during merge stage, but since there is no reloc_ctl at all, we do not need to bother that.

References

Affected packages