CVE-2024-37354

In the Linux kernel, the following vulnerability has been resolved: btrfs: fix crash on racing fsync and size-extending write into prealloc We have been seeing crashes on duplicate keys in btrfs_set_item_key_safe(): BTRFS critical (device vdb): slot 4 key (450 108 8192) new key (450 108 8192) ------------[ cut here ]------------ kernel BUG at fs/btrfs/ctree.c:2620! invalid opcode: 0000 [#1] PREEMPT SMP PTI CPU: 0 PID: 3139 Comm: xfs_io Kdump: loaded Not tainted 6.9.0 #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 RIP: 0010:btrfs_set_item_key_safe+0x11f/0x290 [btrfs] With the following stack trace: #0 btrfs_set_item_key_safe (fs/btrfs/ctree.c:2620:4) #1 btrfs_drop_extents (fs/btrfs/file.c:411:4) #2 log_one_extent (fs/btrfs/tree-log.c:4732:9) #3 btrfs_log_changed_extents (fs/btrfs/tree-log.c:4955:9) #4 btrfs_log_inode (fs/btrfs/tree-log.c:6626:9) #5 btrfs_log_inode_parent (fs/btrfs/tree-log.c:7070:8) #6 btrfs_log_dentry_safe (fs/btrfs/tree-log.c:7171:8) #7 btrfs_sync_file (fs/btrfs/file.c:1933:8) #8 vfs_fsync_range (fs/sync.c:188:9) #9 vfs_fsync (fs/sync.c:202:9) #10 do_fsync (fs/sync.c:212:9) #11 __do_sys_fdatasync (fs/sync.c:225:9) #12 __se_sys_fdatasync (fs/sync.c:223:1) #13 __x64_sys_fdatasync (fs/sync.c:223:1) #14 do_syscall_x64 (arch/x86/entry/common.c:52:14) #15 do_syscall_64 (arch/x86/entry/common.c:83:7) #16 entry_SYSCALL_64+0xaf/0x14c (arch/x86/entry/entry_64.S:121) So we're logging a changed extent from fsync, which is splitting an extent in the log tree. But this split part already exists in the tree, triggering the BUG(). This is the state of the log tree at the time of the crash, dumped with drgn (https://github.com/osandov/drgn/blob/main/contrib/btrfs_tree.py) to get more details than btrfs_print_leaf() gives us: >>> print_extent_buffer(prog.crashed_thread().stack_trace()[0]["eb"]) leaf 33439744 level 0 items 72 generation 9 owner 18446744073709551610 leaf 33439744 flags 0x100000000000000 fs uuid e5bd3946-400c-4223-8923-190ef1f18677 chunk uuid d58cb17e-6d02-494a-829a-18b7d8a399da item 0 key (450 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 7 transid 9 size 8192 nbytes 8473563889606862198 block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0 sequence 204 flags 0x10(PREALLOC) atime 1716417703.220000000 (2024-05-22 15:41:43) ctime 1716417704.983333333 (2024-05-22 15:41:44) mtime 1716417704.983333333 (2024-05-22 15:41:44) otime 17592186044416.000000000 (559444-03-08 01:40:16) item 1 key (450 INODE_REF 256) itemoff 16110 itemsize 13 index 195 namelen 3 name: 193 item 2 key (450 XATTR_ITEM 1640047104) itemoff 16073 itemsize 37 location key (0 UNKNOWN.0 0) type XATTR transid 7 data_len 1 name_len 6 name: user.a data a item 3 key (450 EXTENT_DATA 0) itemoff 16020 itemsize 53 generation 9 type 1 (regular) extent data disk byte 303144960 nr 12288 extent data offset 0 nr 4096 ram 12288 extent compression 0 (none) item 4 key (450 EXTENT_DATA 4096) itemoff 15967 itemsize 53 generation 9 type 2 (prealloc) prealloc data disk byte 303144960 nr 12288 prealloc data offset 4096 nr 8192 item 5 key (450 EXTENT_DATA 8192) itemoff 15914 itemsize 53 generation 9 type 2 (prealloc) prealloc data disk byte 303144960 nr 12288 prealloc data offset 8192 nr 4096 ... So the real problem happened earlier: notice that items 4 (4k-12k) and 5 (8k-12k) overlap. Both are prealloc extents. Item 4 straddles i_size and item 5 starts at i_size. Here is the state of ---truncated---
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:6.10:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.10:rc2:*:*:*:*:*:*

History

17 Sep 2025, 15:49

Type Values Removed Values Added
CVSS v2 : unknown
v3 : unknown
v2 : unknown
v3 : 4.7
CWE CWE-362
CPE cpe:2.3:o:linux:linux_kernel:6.10:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.10:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
First Time Linux
Linux linux Kernel
References () https://git.kernel.org/stable/c/1ff2bd566fbcefcb892be85c493bdb92b911c428 - () https://git.kernel.org/stable/c/1ff2bd566fbcefcb892be85c493bdb92b911c428 - Patch
References () https://git.kernel.org/stable/c/3d08c52ba1887a1ff9c179d4b6a18b427bcb2097 - () https://git.kernel.org/stable/c/3d08c52ba1887a1ff9c179d4b6a18b427bcb2097 - Patch
References () https://git.kernel.org/stable/c/9d274c19a71b3a276949933859610721a453946b - () https://git.kernel.org/stable/c/9d274c19a71b3a276949933859610721a453946b - Patch
References () https://git.kernel.org/stable/c/f4e5ed974876c14d3623e04dc43d3e3281bc6011 - () https://git.kernel.org/stable/c/f4e5ed974876c14d3623e04dc43d3e3281bc6011 - Patch

21 Nov 2024, 09:23

Type Values Removed Values Added
Summary
  • (es) En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: btrfs: corrige el fallo en fsync de ejecucións y escritura de extensión de tamaño en prealloc. Hemos estado viendo fallos en claves duplicadas en btrfs_set_item_key_safe(): BTRFS crítico (dispositivo vdb): clave de ranura 4 ( 450 108 8192) nueva clave (450 108 8192) ------------[ cortar aquí ]------------ ERROR del kernel en fs/btrfs/ctree.c: 2620! código de operación no válido: 0000 [#1] PREEMPT SMP PTI CPU: 0 PID: 3139 Comm: xfs_io Kdump: cargado No contaminado 6.9.0 #6 Nombre de hardware: PC estándar QEMU (i440FX + PIIX, 1996), BIOS 1.16.3-2 .fc40 01/04/2014 RIP: 0010:btrfs_set_item_key_safe+0x11f/0x290 [btrfs] Con el siguiente seguimiento de pila: #0 btrfs_set_item_key_safe (fs/btrfs/ctree.c:2620:4) #1 btrfs_drop_extents (fs/btrfs/file .c:411:4) #2 log_one_extent (fs/btrfs/tree-log.c:4732:9) #3 btrfs_log_changed_extents (fs/btrfs/tree-log.c:4955:9) #4 btrfs_log_inode (fs/btrfs /tree-log.c:6626:9) #5 btrfs_log_inode_parent (fs/btrfs/tree-log.c:7070:8) #6 btrfs_log_dentry_safe (fs/btrfs/tree-log.c:7171:8) #7 btrfs_sync_file (fs/btrfs/file.c:1933:8) #8 vfs_fsync_range (fs/sync.c:188:9) #9 vfs_fsync (fs/sync.c:202:9) #10 do_fsync (fs/sync.c :212:9) #11 __do_sys_fdatasync (fs/sync.c:225:9) #12 __se_sys_fdatasync (fs/sync.c:223:1) #13 __x64_sys_fdatasync (fs/sync.c:223:1) #14 do_syscall_x64 (arch/x86/entry/common.c:52:14) #15 do_syscall_64 (arch/x86/entry/common.c:83:7) #16 Entry_SYSCALL_64+0xaf/0x14c (arch/x86/entry/entry_64.S :121) Así que estamos registrando una extensión modificada desde fsync, que es dividir una extensión en el árbol de registro. Pero esta parte dividida ya existe en el árbol, lo que activa el ERROR(). Este es el estado del árbol de registro en el momento del bloqueo, descargado con drgn (https://github.com/osandov/drgn/blob/main/contrib/btrfs_tree.py) para obtener más detalles de los que proporciona btrfs_print_leaf() nosotros: >>> print_extent_buffer(prog.crashed_thread().stack_trace()[0]["eb"]) hoja 33439744 elementos de nivel 0 72 generación 9 propietario 18446744073709551610 hoja 33439744 banderas 0x100000000000000 fs uuid 00c-4223-8923-190ef1f18677 fragmento uuid d58cb17e-6d02-494a-829a-18b7d8a399da clave del elemento 0 (450 INODE_ITEM 0) itemoff 16123 tamaño del elemento 160 generación 7 transid 9 tamaño 8192 nbytes 8473563889606862198 grupo de bloques 0 modo 100600 enlaces 1 uid 0 gid 0 rdev 0 secuencia 204 banderas 0x10(PREALLOC ) atime 1716417703.220000000 (2024-05-22 15:41:43) ctime 1716417704.983333333 (2024-05-22 15:41:44) mtime 1716417704.983333333 (2024-05-2) 2 15:41:44) otime 17592186044416.000000000 (559444-03- 08 01:40:16) clave del elemento 1 (450 INODE_REF 256) itemoff 16110 tamaño del elemento 13 índice 195 namelen 3 nombre: 193 clave del elemento 2 (450 XATTR_ITEM 1640047104) itemoff 16073 tamaño del elemento 37 clave de ubicación (0 UNKNOWN.0 0) tipo XATTR transid 7 data_len 1 name_len 6 nombre: usuario.a datos a elemento 3 clave (450 EXTENT_DATA 0) itemoff 16020 tamaño de elemento 53 generación 9 tipo 1 (normal) byte de disco de datos de extensión 303144960 nr 12288 desplazamiento de datos de extensión 0 nr 4096 ram 12288 compresión de extensión 0 ( ninguno) clave del elemento 4 (450 EXTENT_DATA 4096) itemoff 15967 tamaño del elemento 53 generación 9 tipo 2 (preasignación) byte de disco de datos de preasignación 303144960 nr 12288 compensación de datos de preasignación 4096 nr 8192 clave del elemento 5 (450 EXTENT_DATA 8192) itemoff 15914 tamaño del elemento 53 generación 9 tipo 2 (preasignación) byte de disco de datos de preasignación 303144960 nr 12288 desplazamiento de datos de preasignación 8192 nr 4096 ... Entonces, el verdadero problema ocurrió antes: observe que los elementos 4 (4k-12k) y 5 (8k-12k) se superponen. Ambas son extensiones de preasignación. El elemento 4 abarca i_size y el elemento 5 comienza en i_size. Aquí está el estado de ---truncado---
References () https://git.kernel.org/stable/c/1ff2bd566fbcefcb892be85c493bdb92b911c428 - () https://git.kernel.org/stable/c/1ff2bd566fbcefcb892be85c493bdb92b911c428 -
References () https://git.kernel.org/stable/c/3d08c52ba1887a1ff9c179d4b6a18b427bcb2097 - () https://git.kernel.org/stable/c/3d08c52ba1887a1ff9c179d4b6a18b427bcb2097 -
References () https://git.kernel.org/stable/c/9d274c19a71b3a276949933859610721a453946b - () https://git.kernel.org/stable/c/9d274c19a71b3a276949933859610721a453946b -
References () https://git.kernel.org/stable/c/f4e5ed974876c14d3623e04dc43d3e3281bc6011 - () https://git.kernel.org/stable/c/f4e5ed974876c14d3623e04dc43d3e3281bc6011 -

25 Jun 2024, 15:15

Type Values Removed Values Added
New CVE

Information

Published : 2024-06-25 15:15

Updated : 2025-09-17 15:49


NVD link : CVE-2024-37354

Mitre link : CVE-2024-37354

CVE.ORG link : CVE-2024-37354


JSON object : View

Products Affected

linux

  • linux_kernel
CWE
CWE-362

Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')