data built 2026-10-19T13:16:53Z

Look up another CVE · open CVE-2025-22115 in the interactive tracker

CVE-2025-22115

btrfs: fix block group refcount race in btrfs_create_pending_block_groups()

7.8 EPSS 0.1% AV:L

Published 2025-04-16 (18 months ago) by the Linux kernel CNA. Subsystem fs/btrfs. Debian urgency: not yet assigned.

What to do, per Debian release

Debian's own status for CVE-2025-22115 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source

ReleaseStatus VersionWhat this means
Debian 12bookwormvulnerable6.1.190-1No fix published anywhere yet, neither in Debian nor upstream for the series bookworm tracks. Watch the Debian tracker page for this CVE. Advisories for bookworm have historically landed a median of 23 days after publication.
Debian 13trixiefixedDSA-5975-1 · 2025-08-13 · text6.12.41-1Update the kernel and reboot. DSA-5975-1 shipped the fix on 2025-08-13, in 6.12.41-1. A running kernel keeps the old code until the machine restarts.
Debian 14forkyfixed6.16.3-1Update the kernel and reboot. Fixed in 6.16.3-1. A running kernel keeps the old code until the machine restarts.
Debian unstablesidfixed6.16.3-1Update the kernel and reboot. Fixed in 6.16.3-1. A running kernel keeps the old code until the machine restarts.

The vulnerability

What the bug is

Block group creation is done in two phases, which results in a slightly unintuitive property: a block group can be allocated/deallocated from after btrfs_make_block_group() adds it to the space_info with btrfs_add_bg_to_space_info(), but before creation is completely completed in btrfs_create_pending_block_groups(). As a result, it is possible for a block group to go unused and have 'btrfs_mark_bg_unused' called on it concurrently with 'btrfs_create_pending_block_groups'. This causes a number of issues, which were fixed with the block group flag 'BLOCK_GROUP_FLAG_NEW'. However, this fix is not quite complete. Since it does not use the unused_bg_lock, it is possible for the following race to occur: btrfs_create_pending_block_groups btrfs_mark_bg_unused if list_empty // false list_del_init clear_bit else if (test_bit) // true list_move_tail And we get into the exact same broken ref count and invalid new_bgs state for transaction cleanup that BLOCK_GROUP_FLAG_NEW was designed to prevent. The broken refcount aspect will result in a warning like: [1272.943527] refcount_t: underflow; use-after-free. [1272.943967] WARNING: CPU: 1 PID: 61 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110 [1272.944731] Modules linked in: btrfs virtio_net xor zstd_compress raid6_pq null_blk [last unloaded: btrfs] [1272.945550] CPU: 1 UID: 0 PID: 61 Comm: kworker/u32:1 Kdump: loaded Tainted: G W 6.14.0-rc5+ #108 [1272.946368] Tainted: [W]=WARN [1272.946585] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014 [1272.947273] Workqueue: btrfs_discard btrfs_discard_workfn [btrfs] [1272.947788] RIP: 0010:refcount_warn_saturate+0xba/0x110 [1272.949532] RSP: 0018:ffffbf1200247df0 EFLAGS: 00010282 [1272.949901] RAX: 0000000000000000 RBX: ffffa14b00e3f800 RCX: 0000000000000000 [1272.950437] RDX: 0000000000000000 RSI: ffffbf1200247c78 RDI: 00000000ffffdfff [1272.950986] RBP: ffffa14b00dc2860 R08: 00000000ffffdfff R09: ffffffff90526268 [1272.951512] R10: ffffffff904762c0 R11: 0000000063666572 R12: ffffa14b00dc28c0 [1272.952024] R13: 0000000000000000 R14: ffffa14b00dc2868 R15: 000001285dcd12c0 [1272.952850] FS: 0000000000000000(0000) GS:ffffa14d33c40000(0000) knlGS:0000000000000000 [1272.953458] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [1272.953931] CR2: 00007f838cbda000 CR3: 000000010104e000 CR4: 00000000000006f0 [1272.954474] Call Trace: [1272.954655] <TASK> [1272.954812] ? refcount_warn_saturate+0xba/0x110 [1272.955173] ? __warn.cold+0x93/0xd7 [1272.955487] ? refcount_warn_saturate+0xba/0x110 [1272.955816] ? report_bug+0xe7/0x120 [1272.956103] ? handle_bug+0x53/0x90 [1272.956424] ? exc_invalid_op+0x13/0x60 [1272.956700] ? asm_exc_invalid_op+0x16/0x20 [1272.957011] ? refcount_warn_saturate+0xba/0x110 [1272.957399] btrfs_discard_cancel_work.cold+0x26/0x2b [btrfs] [1272.957853] btrfs_put_block_group.cold+0x5d/0x8e [btrfs] [1272.958289] btrfs_discard_workfn+0x194/0x380 [btrfs] [1272.958729] process_one_work+0x130/0x290 [1272.959026] worker_thread+0x2ea/0x420 [1272.959335] ? __pfx_worker_thread+0x10/0x10 [1272.959644] kthread+0xd7/0x1c0 [1272.959872] ? __pfx_kthread+0x10/0x10 [1272.960172] ret_from_fork+0x30/0x50 [1272.960474] ? __pfx_kthread+0x10/0x10 [1272.960745] ret_from_fork_asm+0x1a/0x30 [1272.961035] </TASK> [1272.961238] ---[ end trace 0000000000000000 ]--- Though we have seen them in the async discard workfn as well. It is most likely to happen after a relocation finishes which cancels discard, tears down the block group, etc. Fix this fully by taking the lock arou ---truncated---

Where it lives

The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.

fs/btrfs/block-group.c

What this is
BTRFS FILE SYSTEMMAINTAINERS section matched on fs/btrfs/ · linux-btrfs@vger.kernel.org · Maintained
Kernel module
btrfs

Check it on the machine

grep -w CONFIG_BTRFS_FS /boot/config-$(uname -r)

Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.

lsmod | grep -w btrfs

Prints a line if that module is loaded right now, and nothing if it is not. One that is not loaded can still be loaded later by anything that needs it.

Show whether Debian builds this, per release

Debian builds this as a loadable module. Every release below compiles it as a module on every flavour, so whether the code is in the running kernel depends on whether that module is loaded.

  • bookworm, trixie, forky, sidm
m
a loadable module on every flavour - check lsmod, can be blacklisted
Build switch
CONFIG_BTRFS_FS

From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages

Signals

Published
2025-04-16 (18 months ago)source
CVSS
7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it
Attack vector
local (AV:L)source
EPSS
0.15%, higher than 3.6% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
not yet assignedsource
Subsystem
fs/btrfs

Upstream fixes

The versions the CNA records as introducing and fixing this, and the commit for each. source

IntroducedFixed inCommit
6.56.12.40ee56da95f896
6.56.14.29d383a6fc592
6.56.152d8e5168d48a
6.1.4700
6.4.1200

Debian advisories

AdvisoryDateShipped toDebian
DSA-5975-12025-08-13trixie 6.12.41-1tracker

Why the CNA scored it this way

Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source

AV:LAttack vector, local
The vulnerability is reached through ordinary filesystem write/delete syscalls against a mounted btrfs filesystem, requiring a local account on the system. There is no network-facing entry point into btrfs chunk/block-group allocation.
AC:LAttack complexity, low
The attacker drives both sides of the race — one thread forces new chunk/block-group creation via writes, another frees the last extents in that group so btrfs_mark_bg_unused() fires — and can retry the interleaving indefinitely with high thread concurrency. No special kernel config or mount option is required, since the default (non-discard=async) btrfs_update_block_group() path calls btrfs_mark_bg_unused() directly.
PR:LPrivileges required, low
Only write access to any btrfs filesystem is needed, which an unprivileged local user has on the common case of a btrfs root/home/tmp; no capability, CAP_SYS_ADMIN, or ioctl gate exists on this path. No privileged operation such as balance is required — the generic extent-free path suffices.
UI:NUser interaction, none
The filesystem is already mounted in the normal case and the attacker triggers everything itself with plain write/unlink activity. No victim action of any kind is needed.
S:UScope, unchanged
The corrupted object and all its consequences are inside the kernel's own security authority; there is no crossing of a VM, IOMMU, or sandbox boundary. This is a standard kernel-local memory-safety issue.
C:HConfidentiality impact, high
The premature refcount drop frees struct btrfs_block_group while it remains reachable from the block-group rbtree, space_info lists, and discard/dirty lists, so kernel workers keep reading attacker-reclaimable slab memory. Since the object comes from a generic kmalloc cache, the attacker can spray it and turn the stale dereferences into an arbitrary kernel-memory read primitive.
I:HIntegrity impact, high
The freed-but-still-linked block group is later written through and unlinked (list_del/list_move on bg_list, discard_list, dirty_list), giving a classic unlink write-what-where once the slot is reclaimed with attacker-controlled data. Its embedded pointers (free_space_ctl, physical_map, inode, caching_ctl) are dereferenced afterwards, making control-flow hijack and privilege escalation feasible.
A:HAvailability impact, high
Even unexploited, the bug produces refcount underflow WARNs, corrupted new_bgs/unused_bgs list state, and use-after-free of a structure central to allocation, which reliably leads to oops/panic and an unusable filesystem. The reported crash occurs in a btrfs kernel worker thread, taking down the whole system rather than just the attacking task.