Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

CVE-2025-39779

Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
11/09/2025
Última modificación:
15/09/2025

Descripción

*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> btrfs: subpage: keep TOWRITE tag until folio is cleaned<br /> <br /> btrfs_subpage_set_writeback() calls folio_start_writeback() the first time<br /> a folio is written back, and it also clears the PAGECACHE_TAG_TOWRITE tag<br /> even if there are still dirty blocks in the folio. This can break ordering<br /> guarantees, such as those required by btrfs_wait_ordered_extents().<br /> <br /> That ordering breakage leads to a real failure. For example, running<br /> generic/464 on a zoned setup will hit the following ASSERT. This happens<br /> because the broken ordering fails to flush existing dirty pages before the<br /> file size is truncated.<br /> <br /> assertion failed: !list_empty(&amp;ordered-&gt;list) :: 0, in fs/btrfs/zoned.c:1899<br /> ------------[ cut here ]------------<br /> kernel BUG at fs/btrfs/zoned.c:1899!<br /> Oops: invalid opcode: 0000 [#1] SMP NOPTI<br /> CPU: 2 UID: 0 PID: 1906169 Comm: kworker/u130:2 Kdump: loaded Not tainted 6.16.0-rc6-BTRFS-ZNS+ #554 PREEMPT(voluntary)<br /> Hardware name: Supermicro Super Server/H12SSL-NT, BIOS 2.0 02/22/2021<br /> Workqueue: btrfs-endio-write btrfs_work_helper [btrfs]<br /> RIP: 0010:btrfs_finish_ordered_zoned.cold+0x50/0x52 [btrfs]<br /> RSP: 0018:ffffc9002efdbd60 EFLAGS: 00010246<br /> RAX: 000000000000004c RBX: ffff88811923c4e0 RCX: 0000000000000000<br /> RDX: 0000000000000000 RSI: ffffffff827e38b1 RDI: 00000000ffffffff<br /> RBP: ffff88810005d000 R08: 00000000ffffdfff R09: ffffffff831051c8<br /> R10: ffffffff83055220 R11: 0000000000000000 R12: ffff8881c2458c00<br /> R13: ffff88811923c540 R14: ffff88811923c5e8 R15: ffff8881c1bd9680<br /> FS: 0000000000000000(0000) GS:ffff88a04acd0000(0000) knlGS:0000000000000000<br /> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br /> CR2: 00007f907c7a918c CR3: 0000000004024000 CR4: 0000000000350ef0<br /> Call Trace:<br /> <br /> ? srso_return_thunk+0x5/0x5f<br /> btrfs_finish_ordered_io+0x4a/0x60 [btrfs]<br /> btrfs_work_helper+0xf9/0x490 [btrfs]<br /> process_one_work+0x204/0x590<br /> ? srso_return_thunk+0x5/0x5f<br /> worker_thread+0x1d6/0x3d0<br /> ? __pfx_worker_thread+0x10/0x10<br /> kthread+0x118/0x230<br /> ? __pfx_kthread+0x10/0x10<br /> ret_from_fork+0x205/0x260<br /> ? __pfx_kthread+0x10/0x10<br /> ret_from_fork_asm+0x1a/0x30<br /> <br /> <br /> Consider process A calling writepages() with WB_SYNC_NONE. In zoned mode or<br /> for compressed writes, it locks several folios for delalloc and starts<br /> writing them out. Let&amp;#39;s call the last locked folio folio X. Suppose the<br /> write range only partially covers folio X, leaving some pages dirty.<br /> Process A calls btrfs_subpage_set_writeback() when building a bio. This<br /> function call clears the TOWRITE tag of folio X, whose size = 8K and<br /> the block size = 4K. It is following state.<br /> <br /> 0 4K 8K<br /> |/////|/////| (flag: DIRTY, tag: DIRTY)<br /> Process A will write this range.<br /> <br /> Now suppose process B concurrently calls writepages() with WB_SYNC_ALL. It<br /> calls tag_pages_for_writeback() to tag dirty folios with<br /> PAGECACHE_TAG_TOWRITE. Since folio X is still dirty, it gets tagged. Then,<br /> B collects tagged folios using filemap_get_folios_tag() and must wait for<br /> folio X to be written before returning from writepages().<br /> <br /> 0 4K 8K<br /> |/////|/////| (flag: DIRTY, tag: DIRTY|TOWRITE)<br /> <br /> However, between tagging and collecting, process A may call<br /> btrfs_subpage_set_writeback() and clear folio X&amp;#39;s TOWRITE tag.<br /> 0 4K 8K<br /> | |/////| (flag: DIRTY|WRITEBACK, tag: DIRTY)<br /> <br /> As a result, process B won&amp;#39;t see folio X in its batch, and returns without<br /> waiting for it. This breaks the WB_SYNC_ALL ordering requirement.<br /> <br /> Fix this by using btrfs_subpage_set_writeback_keepwrite(), which retains<br /> the TOWRITE tag. We now manually clear the tag only after the folio becomes<br /> clean, via the xas operation.

Impacto