CVE-2025-39779 in Linuxinfo

Summary

by MITRE • 09/11/2025

In the Linux kernel, the following vulnerability has been resolved:

btrfs: subpage: keep TOWRITE tag until folio is cleaned

btrfs_subpage_set_writeback() calls folio_start_writeback() the first time a folio is written back, and it also clears the PAGECACHE_TAG_TOWRITE tag even if there are still dirty blocks in the folio. This can break ordering guarantees, such as those required by btrfs_wait_ordered_extents().

That ordering breakage leads to a real failure. For example, running generic/464 on a zoned setup will hit the following ASSERT. This happens because the broken ordering fails to flush existing dirty pages before the file size is truncated.

assertion failed: !list_empty(&ordered->list) :: 0, in fs/btrfs/zoned.c:1899 ------------[ cut here ]------------
kernel BUG at fs/btrfs/zoned.c:1899! Oops: invalid opcode: 0000 [#1] SMP NOPTI
CPU: 2 UID: 0 PID: 1906169 Comm: kworker/u130:2 Kdump: loaded Not tainted 6.16.0-rc6-BTRFS-ZNS+ #554 PREEMPT(voluntary) Hardware name: Supermicro Super Server/H12SSL-NT, BIOS 2.0 02/22/2021 Workqueue: btrfs-endio-write btrfs_work_helper [btrfs]
RIP: 0010:btrfs_finish_ordered_zoned.cold+0x50/0x52 [btrfs]
RSP: 0018:ffffc9002efdbd60 EFLAGS: 00010246 RAX: 000000000000004c RBX: ffff88811923c4e0 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff827e38b1 RDI: 00000000ffffffff RBP: ffff88810005d000 R08: 00000000ffffdfff R09: ffffffff831051c8 R10: ffffffff83055220 R11: 0000000000000000 R12: ffff8881c2458c00 R13: ffff88811923c540 R14: ffff88811923c5e8 R15: ffff8881c1bd9680 FS: 0000000000000000(0000) GS:ffff88a04acd0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f907c7a918c CR3: 0000000004024000 CR4: 0000000000350ef0 Call Trace: <TASK> ? srso_return_thunk+0x5/0x5f btrfs_finish_ordered_io+0x4a/0x60 [btrfs]
btrfs_work_helper+0xf9/0x490 [btrfs]
process_one_work+0x204/0x590 ? srso_return_thunk+0x5/0x5f worker_thread+0x1d6/0x3d0 ? __pfx_worker_thread+0x10/0x10 kthread+0x118/0x230 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x205/0x260 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK>

Consider process A calling writepages() with WB_SYNC_NONE. In zoned mode or for compressed writes, it locks several folios for delalloc and starts writing them out. Let's call the last locked folio folio X. Suppose the write range only partially covers folio X, leaving some pages dirty. Process A calls btrfs_subpage_set_writeback() when building a bio. This function call clears the TOWRITE tag of folio X, whose size = 8K and the block size = 4K. It is following state.

0 4K 8K |/////|/////| (flag: DIRTY, tag: DIRTY) <-----> Process A will write this range.

Now suppose process B concurrently calls writepages() with WB_SYNC_ALL. It calls tag_pages_for_writeback() to tag dirty folios with PAGECACHE_TAG_TOWRITE. Since folio X is still dirty, it gets tagged. Then, B collects tagged folios using filemap_get_folios_tag() and must wait for folio X to be written before returning from writepages().

0 4K 8K |/////|/////| (flag: DIRTY, tag: DIRTY|TOWRITE)

However, between tagging and collecting, process A may call btrfs_subpage_set_writeback() and clear folio X's TOWRITE tag. 0 4K 8K | |/////| (flag: DIRTY|WRITEBACK, tag: DIRTY)

As a result, process B won't see folio X in its batch, and returns without waiting for it. This breaks the WB_SYNC_ALL ordering requirement.

Fix this by using btrfs_subpage_set_writeback_keepwrite(), which retains the TOWRITE tag. We now manually clear the tag only after the folio becomes clean, via the xas operation.

If you want to get best quality of vulnerability data, you may have to visit VulDB.

Analysis

by VulDB Data Team • 11/27/2025

The vulnerability described in CVE-2025-39779 affects the Linux kernel's btrfs file system implementation, specifically within the subpage writeback handling mechanism. This issue stems from improper management of the PAGECACHE_TAG_TOWRITE tag during folio writeback operations, which can lead to violation of critical ordering guarantees required by the file system's internal consistency mechanisms. The problem manifests particularly in zoned storage environments where strict ordering of I/O operations is essential for maintaining data integrity and preventing corruption during file truncation operations.

The technical flaw occurs in the btrfs_subpage_set_writeback() function which is responsible for initiating writeback operations on folios containing dirty data. When this function is called, it not only starts the writeback process by invoking folio_start_writeback() but also prematurely clears the PAGECACHE_TAG_TOWRITE tag even when the folio still contains dirty blocks. This premature tag clearing creates a race condition between concurrent write operations where one process may tag a folio for writeback while another process clears the tag before the tagging process can collect and wait for that folio. The vulnerability is particularly evident when dealing with folios that are larger than the block size, such as 8KB folios with 4KB block boundaries, where partial writes leave some pages dirty while others are being written back.

The operational impact of this vulnerability is severe as it can cause assertion failures and kernel oops conditions, specifically triggering the assertion at fs/btrfs/zoned.c:1899 which checks for non-empty ordered lists. This leads to kernel panics and system instability when running specific test cases like generic/464 on zoned storage setups. The ordering guarantee violation affects the btrfs_wait_ordered_extents() function which is crucial for ensuring that all ordered extents are properly flushed before file size truncation operations occur. This can result in data loss, file system corruption, and complete system crashes when concurrent write operations with different synchronization levels (WB_SYNC_NONE vs WB_SYNC_ALL) interact improperly with the same folio.

The fix implemented addresses this issue by modifying the writeback handling to use btrfs_subpage_set_writeback_keepwrite() instead of the problematic function. This change ensures that the TOWRITE tag remains set until the folio is completely cleaned, rather than being cleared prematurely during the initial writeback initiation. The solution involves manually clearing the tag only after the folio becomes clean through explicit xas (extent access) operations, which maintains proper synchronization between concurrent write operations and preserves the expected ordering semantics. This approach aligns with the principle of maintaining consistent state management in concurrent environments and follows the ATT&CK framework's concept of privilege escalation through system-level vulnerabilities. The fix also corresponds to CWE-129, which deals with improper handling of buffer overruns and memory management issues, as it prevents the improper state transitions that can lead to system instability and data corruption in the btrfs file system implementation.

Responsible

Linux

Reservation

04/16/2025

Disclosure

09/11/2025

Moderation

accepted

CPE

ready

EPSS

0.00134

KEV

no

Activities

very low

Sources

Interested in the pricing of exploits?

See the underground prices here!