CVE-2024-49868

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: FAULT_INJECTION: forcing a failure. start_transaction+0x830/0x1670 fs/btrfs/transaction.c:676 prepare_to_relocate+0x31f/0x4c0 fs/btrfs/relocation.c:3642 relocate_block_group+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:btrfs_update_reloc_root+0x362/0xa80 fs/btrfs/relocation.c:926 Call Trace: <TASK> commit_fs_roots+0x2ee/0x720 fs/btrfs/transaction.c:1496 btrfs_commit_transaction+0xfaf/0x3740 fs/btrfs/transaction.c:2430 del_balance_item fs/btrfs/volumes.c:3678 [inline] reset_balance_state+0x25e/0x3c0 fs/btrfs/volumes.c:3742 btrfs_balance+0xead/0x10c0 fs/btrfs/volumes.c:4574 btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f [CAUSE] The allocation failure happens at the start_transaction() inside prepare_to_relocate(), and during the error handling we call unset_reloc_control(), which makes fs_info->balance_ctl to be NULL. Then we continue the error path cleanup in btrfs_balance() by calling reset_balance_state() which will call del_balance_item() to fully delete the balance item in the root tree. However during the small window between set_reloc_contrl() and unset_reloc_control(), we can have a subvolume tree update and created a reloc_root for that subvolume. Then we go into the final btrfs_commit_transaction() of del_balance_item(), and into btrfs_update_reloc_root() inside commit_fs_roots(). That function checks if fs_info->reloc_ctl is in the merge_reloc_tree stage, but since fs_info->reloc_ctl is NULL, it results a NULL pointer dereference. [FIX] Just add extra check on fs_info->reloc_ctl inside btrfs_update_reloc_root(), before checking fs_info->reloc_ctl->merge_reloc_tree. That DEAD_RELOC_TREE 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.
Configurations

Configuration 1 (hide)

OR cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*

History

08 Nov 2024, 16:15

Type Values Removed Values Added
References
  • () https://git.kernel.org/stable/c/1282f001cbf56e5dd6e90a18e205a566793f4be0 -

25 Oct 2024, 12:54

Type Values Removed Values Added
CWE CWE-476
CPE cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
References () https://git.kernel.org/stable/c/37fee9c220b92c3b7bf22b51c51dde5364e7590b - () https://git.kernel.org/stable/c/37fee9c220b92c3b7bf22b51c51dde5364e7590b - Patch
References () https://git.kernel.org/stable/c/39356ec0e319ed07627b3a0f402d0608546509e6 - () https://git.kernel.org/stable/c/39356ec0e319ed07627b3a0f402d0608546509e6 - Patch
References () https://git.kernel.org/stable/c/7ad0c5868f2f0418619089513d95230c66cb7eb4 - () https://git.kernel.org/stable/c/7ad0c5868f2f0418619089513d95230c66cb7eb4 - Patch
References () https://git.kernel.org/stable/c/c3b47f49e83197e8dffd023ec568403bcdbb774b - () https://git.kernel.org/stable/c/c3b47f49e83197e8dffd023ec568403bcdbb774b - Patch
References () https://git.kernel.org/stable/c/d13249c0df7aab885acb149695f82c54c0822a70 - () https://git.kernel.org/stable/c/d13249c0df7aab885acb149695f82c54c0822a70 - Patch
References () https://git.kernel.org/stable/c/d73d48acf36f57362df7e4f9d76568168bf5e944 - () https://git.kernel.org/stable/c/d73d48acf36f57362df7e4f9d76568168bf5e944 - Patch
References () https://git.kernel.org/stable/c/dc02c1440705e3451abd1c2c8114a5c1bb188e9f - () https://git.kernel.org/stable/c/dc02c1440705e3451abd1c2c8114a5c1bb188e9f - Patch
CVSS v2 : unknown
v3 : unknown
v2 : unknown
v3 : 5.5
First Time Linux linux Kernel
Linux

23 Oct 2024, 15:13

Type Values Removed Values Added
Summary
  • (es) En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: btrfs: corrige una desreferencia de puntero NULL cuando no se puede iniciar una nueva transacción [ERROR] Syzbot informó una desreferencia de puntero NULL con el siguiente bloqueo: FAULT_INJECTION: forzando un fallo. start_transaction+0x830/0x1670 fs/btrfs/transaction.c:676 prepare_to_relocate+0x31f/0x4c0 fs/btrfs/relocation.c:3642 relocate_block_group+0x169/0xd20 fs/btrfs/relocation.c:3678 ... Información de BTRFS (dispositivo loop0): balance: finalizado con estado: -12 Vaya: error de protección general, probablemente para la dirección no canónica 0xdffffc00000000cc: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref en el rango [0x000000000000660-0x0000000000000667] RIP: 0010:btrfs_update_reloc_root+0x362/0xa80 fs/btrfs/relocation.c:926 Seguimiento de llamadas: commit_fs_roots+0x2ee/0x720 fs/btrfs/transaction.c:1496 btrfs_commit_transaction+0xfaf/0x3740 fs/btrfs/transaction.c:2430 del_balance_item fs/btrfs/volumes.c:3678 [en línea] reset_balance_state+0x25e/0x3c0 fs/btrfs/volumes.c:3742 btrfs_balance+0xead/0x10c0 fs/btrfs/volumes.c:4574 btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f [CAUSA] El fallo de asignación ocurre en start_transaction() dentro de prepare_to_relocate(), y durante el manejo de errores llamamos a unset_reloc_control(), lo que hace que fs_info-&gt;balance_ctl sea NULL. Luego continuamos con la limpieza de la ruta de error en btrfs_balance() llamando a reset_balance_state() que llamará a del_balance_item() para eliminar por completo el elemento de balance en el árbol raíz. Sin embargo, durante la pequeña ventana entre set_reloc_contrl() y unset_reloc_control(), podemos tener una actualización del árbol de subvolumen y crear un reloc_root para ese subvolumen. Luego pasamos a la btrfs_commit_transaction() final de del_balance_item() y a btrfs_update_reloc_root() dentro de commit_fs_roots(). Esa función verifica si fs_info-&gt;reloc_ctl está en la etapa merge_reloc_tree, pero dado que fs_info-&gt;reloc_ctl es NULL, da como resultado una desreferencia de puntero NULL. [SOLUCIÓN] Solo hay que añadir una comprobación adicional en fs_info-&gt;reloc_ctl dentro de btrfs_update_reloc_root(), antes de comprobar fs_info-&gt;reloc_ctl-&gt;merge_reloc_tree. El manejo de DEAD_RELOC_TREE sirve para evitar modificaciones adicionales del árbol de reubicación durante la etapa de fusión, pero como no hay ningún reloc_ctl, no tenemos que preocuparnos por eso.

21 Oct 2024, 18:15

Type Values Removed Values Added
New CVE

Information

Published : 2024-10-21 18:15

Updated : 2024-11-08 16:15


NVD link : CVE-2024-49868

Mitre link : CVE-2024-49868

CVE.ORG link : CVE-2024-49868


JSON object : View

Products Affected

linux

  • linux_kernel
CWE
CWE-476

NULL Pointer Dereference