CVE-2025-71183
Publication date:
31/01/2026
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
btrfs: always detect conflicting inodes when logging inode refs<br />
<br />
After rename exchanging (either with the rename exchange operation or<br />
regular renames in multiple non-atomic steps) two inodes and at least<br />
one of them is a directory, we can end up with a log tree that contains<br />
only of the inodes and after a power failure that can result in an attempt<br />
to delete the other inode when it should not because it was not deleted<br />
before the power failure. In some case that delete attempt fails when<br />
the target inode is a directory that contains a subvolume inside it, since<br />
the log replay code is not prepared to deal with directory entries that<br />
point to root items (only inode items).<br />
<br />
1) We have directories "dir1" (inode A) and "dir2" (inode B) under the<br />
same parent directory;<br />
<br />
2) We have a file (inode C) under directory "dir1" (inode A);<br />
<br />
3) We have a subvolume inside directory "dir2" (inode B);<br />
<br />
4) All these inodes were persisted in a past transaction and we are<br />
currently at transaction N;<br />
<br />
5) We rename the file (inode C), so at btrfs_log_new_name() we update<br />
inode C&#39;s last_unlink_trans to N;<br />
<br />
6) We get a rename exchange for "dir1" (inode A) and "dir2" (inode B),<br />
so after the exchange "dir1" is inode B and "dir2" is inode A.<br />
During the rename exchange we call btrfs_log_new_name() for inodes<br />
A and B, but because they are directories, we don&#39;t update their<br />
last_unlink_trans to N;<br />
<br />
7) An fsync against the file (inode C) is done, and because its inode<br />
has a last_unlink_trans with a value of N we log its parent directory<br />
(inode A) (through btrfs_log_all_parents(), called from<br />
btrfs_log_inode_parent()).<br />
<br />
8) So we end up with inode B not logged, which now has the old name<br />
of inode A. At copy_inode_items_to_log(), when logging inode A, we<br />
did not check if we had any conflicting inode to log because inode<br />
A has a generation lower than the current transaction (created in<br />
a past transaction);<br />
<br />
9) After a power failure, when replaying the log tree, since we find that<br />
inode A has a new name that conflicts with the name of inode B in the<br />
fs tree, we attempt to delete inode B... this is wrong since that<br />
directory was never deleted before the power failure, and because there<br />
is a subvolume inside that directory, attempting to delete it will fail<br />
since replay_dir_deletes() and btrfs_unlink_inode() are not prepared<br />
to deal with dir items that point to roots instead of inodes.<br />
<br />
When that happens the mount fails and we get a stack trace like the<br />
following:<br />
<br />
[87.2314] BTRFS info (device dm-0): start tree-log replay<br />
[87.2318] BTRFS critical (device dm-0): failed to delete reference to subvol, root 5 inode 256 parent 259<br />
[87.2332] ------------[ cut here ]------------<br />
[87.2338] BTRFS: Transaction aborted (error -2)<br />
[87.2346] WARNING: CPU: 1 PID: 638968 at fs/btrfs/inode.c:4345 __btrfs_unlink_inode+0x416/0x440 [btrfs]<br />
[87.2368] Modules linked in: btrfs loop dm_thin_pool (...)<br />
[87.2470] CPU: 1 UID: 0 PID: 638968 Comm: mount Tainted: G W 6.18.0-rc7-btrfs-next-218+ #2 PREEMPT(full)<br />
[87.2489] Tainted: [W]=WARN<br />
[87.2494] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014<br />
[87.2514] RIP: 0010:__btrfs_unlink_inode+0x416/0x440 [btrfs]<br />
[87.2538] Code: c0 89 04 24 (...)<br />
[87.2568] RSP: 0018:ffffc0e741f4b9b8 EFLAGS: 00010286<br />
[87.2574] RAX: 0000000000000000 RBX: ffff9d3ec8a6cf60 RCX: 0000000000000000<br />
[87.2582] RDX: 0000000000000002 RSI: ffffffff84ab45a1 RDI: 00000000ffffffff<br />
[87.2591] RBP: ffff9d3ec8a6ef20 R08: 0000000000000000 R09: ffffc0e741f4b840<br />
[87.2599] R10: ffff9d45dc1fffa8 R11: 0000000000000003 R12: ffff9d3ee26d77e0<br />
[87.2608] R13: ffffc0e741f4ba98 R14: ffff9d4458040800 R15: ffff9d44b6b7ca10<br />
[87.2618] FS: 00007f7b9603a840(0000) GS:ffff9d4658982000(0000) knlGS:0000000000000000<br />
[87.<br />
---truncated---
Severity CVSS v4.0: Pending analysis
Last modification:
31/01/2026