CVE-2024-37354CWE-362

CVE-2024-37354

High · published June 25, 2024

CVSS v3.1
7.8
EPSS
0%
Percentile
6.4
In the wild
Unconfirmed
What it is

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

The record
Technical detail
CVSS v3.1
7.8 · HIGH
Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0
Not supplied
EPSS
0.00173 · 6.4th percentile
Weakness
CWE-362 · Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Published
2024-06-25T19:15Z
Affected products (5)
ProductVersionsFixed in
linux/linux_kernel< 6.1.946.1.94
linux/linux_kernel≥ 6.2, < 6.6.346.6.34
linux/linux_kernel≥ 6.7, < 6.9.56.9.5
linux/linux_kernelall versions—
linux/linux_kernelall versions—
References (9)
EPSS history
Timeline
  • 25 JUN 14:22Z
    btrfs: fix crash on racing fsync and size-extending write into prealloc
    cvelistv5