Skip to main content

Linux Kernel btrfs CVE-2025-38365

MEDIUM
Race Condition (CWE-362)
2025-07-25 416baaa9-dc9f-4396-8d5f-8c081fb06d67
4.7
CVSS 3.1 · NVD
Share

Severity by source

NVD PRIMARY
4.7 MEDIUM
AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H
vuln.today AI
6.3 MEDIUM

Local access and race-condition timing (AC:H, PR:L) preserved from official vector; I:H added because permanent file deletion is an integrity failure, not merely availability loss.

3.1 AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H
4.0 AV:L/AC:H/AT:P/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N
SUSE
6.3 MEDIUM
AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H

Primary rating from NVD.

CVSS VectorNVD

Attack Vector
Local
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

Lifecycle Timeline

1
Analysis Generated
Jul 30, 2026 - 08:57 vuln.today

DescriptionNVD

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

btrfs: fix a race between renames and directory logging

We have a race between a rename and directory inode logging that if it happens and we crash/power fail before the rename completes, the next time the filesystem is mounted, the log replay code will end up deleting the file that was being renamed.

This is best explained following a step by step analysis of an interleaving of steps that lead into this situation.

Consider the initial conditions:

  1. We are at transaction N;
  2. We have directories A and B created in a past transaction (< N);
  3. We have inode X corresponding to a file that has 2 hardlinks, one in

directory A and the other in directory B, so we'll name them as "A/foo_link1" and "B/foo_link2". Both hard links were persisted in a past transaction (< N);

  1. We have inode Y corresponding to a file that as a single hard link and

is located in directory A, we'll name it as "A/bar". This file was also persisted in a past transaction (< N).

The steps leading to a file loss are the following and for all of them we are under transaction N:

  1. Link "A/foo_link1" is removed, so inode's X last_unlink_trans field

is updated to N, through btrfs_unlink() -> btrfs_record_unlink_dir();

  1. Task A starts a rename for inode Y, with the goal of renaming from

"A/bar" to "A/baz", so we enter btrfs_rename();

  1. Task A inserts the new BTRFS_INODE_REF_KEY for inode Y by calling

btrfs_insert_inode_ref();

  1. Because the rename happens in the same directory, we don't set the

last_unlink_trans field of directoty A's inode to the current transaction id, that is, we don't cal btrfs_record_unlink_dir();

  1. Task A then removes the entries from directory A (BTRFS_DIR_ITEM_KEY

and BTRFS_DIR_INDEX_KEY items) when calling __btrfs_unlink_inode() (actually the dir index item is added as a delayed item, but the effect is the same);

  1. Now before task A adds the new entry "A/baz" to directory A by

calling btrfs_add_link(), another task, task B is logging inode X;

  1. Task B starts a fsync of inode X and after logging inode X, at

btrfs_log_inode_parent() it calls btrfs_log_all_parents(), since inode X has a last_unlink_trans value of N, set at in step 1;

  1. At btrfs_log_all_parents() we search for all parent directories of

inode X using the commit root, so we find directories A and B and log them. Bu when logging direct A, we don't have a dir index item for inode Y anymore, neither the old name "A/bar" nor for the new name "A/baz" since the rename has deleted the old name but has not yet inserted the new name - task A hasn't called yet btrfs_add_link() to do that.

Note that logging directory A doesn't fallback to a transaction commit because its last_unlink_trans has a lower value than the current transaction's id (see step 4);

  1. Task B finishes logging directories A and B and gets back to

btrfs_sync_file() where it calls btrfs_sync_log() to persist the log tree;

  1. Task B successfully persisted the log tree, btrfs_sync_log() completed

with success, and a power failure happened.

We have a log tree without any directory entry for inode Y, so the log replay code deletes the entry for inode Y, name "A/bar", from the subvolume tree since it doesn't exist in the log tree and the log tree is authorative for its index (we logged a BTRFS_DIR_LOG_INDEX_KEY item that covers the index range for the dentry that corresponds to "A/bar").

Since there's no other hard link for inode Y and the log replay code deletes the name "A/bar", the file is lost.

The issue wouldn't happen if task B synced the log only after task A called btrfs_log_new_name(), which would update the log with the new name for inode Y ("A/bar").

Fix this by pinning the log root during renames before removing the old directory entry, and unpinning af ---truncated---

AnalysisAI

Btrfs in the Linux kernel contains a race condition between same-directory rename operations and directory inode logging that can cause permanent, unrecoverable file loss after a crash or power failure. When a rename removes the old directory entry but has not yet inserted the new one, a concurrent fsync of a related inode can log the parent directory in this transient, inconsistent state and persist it to the log tree. If a power failure occurs immediately after that log flush, log replay on the next mount deletes the renamed file entirely, with no remaining hard links to recover it. No public exploit has been identified at time of analysis; the EPSS score of 0.11% (2nd percentile) reflects low opportunistic exploitation probability, though the impact for affected btrfs deployments is severe and permanent.

Technical ContextAI

The vulnerability resides in the btrfs subsystem of the Linux kernel, specifically in the interaction between btrfs_rename() and btrfs_log_inode_parent() / btrfs_log_all_parents(), identified by CPE cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*. Btrfs maintains a separate log tree for fsync-driven crash recovery; log replay is authoritative for the directory index ranges it covers, meaning entries absent from the log are actively deleted from the subvolume tree during replay. The root cause (CWE-362: Concurrent Execution Using Shared Resource with Improper Synchronization) is that btrfs_rename() for same-directory renames does not update the parent directory's last_unlink_trans field to the current transaction ID. This field is the sentinel that causes a directory's logging path to fall back to a full transaction commit rather than a partial log flush. Without that update, a concurrent logger observing the directory sees no reason to defer, captures the directory after the old BTRFS_DIR_ITEM_KEY and BTRFS_DIR_INDEX_KEY are removed but before the new entries are inserted, and persists this half-state to the log tree. The fix pins the log root before the old entry is removed and unpins it only after the new entry is added, making the rename atomic from the logger's perspective.

RemediationAI

The primary fix is available as five upstream kernel commits at git.kernel.org/stable: 2088895d5903082bb9021770b919e733c57edbc1, 3ca864de852bc91007b32d2a0d48993724f4abad, 51bd363c7010d033d3334daf457c824484bf9bf0, 8c6874646c21bd820cf475e2874e62c133954023, and aeeae8feeaae4445a86f9815273e81f902dc1f5b. These represent backports across multiple stable branches. Debian LTS users should apply the update announced at lists.debian.org/debian-lts-announce/2025/10/msg00008.html. Exact fixed kernel versions per stable branch are not independently confirmed from the available input data - consult your distribution's security advisories for the precise update package. If an immediate kernel update is not feasible, the risk can be reduced (not eliminated) by migrating critical data volumes from btrfs to ext4 or xfs, which are not affected by this race; however, this requires reformatting and is only practical for new deployments. Disabling concurrent fsync-heavy workloads on btrfs volumes is not a reliable mitigation given that the race can arise from normal application behavior.

CVE-2021-44228 CRITICAL POC
10.0 Dec 10

Apache Log4j2 contains a critical JNDI injection vulnerability known as 'Log4Shell' that allows unauthenticated remote c

CVE-2019-11043 CRITICAL POC
9.8 Oct 28

In PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 in certain configurations of FPM setup it

CVE-2012-1823 CRITICAL POC
9.8 May 11

sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not

CVE-2014-6271 CRITICAL POC
9.8 Sep 24

GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which

CVE-2017-7494 CRITICAL POC
9.8 May 30

Samba since version 3.5.0 and before 4.6.4, 4.5.10 and 4.4.14 is vulnerable to remote code execution vulnerability, allo

CVE-2012-0507 CRITICAL POC
9.8 Jun 07

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 2 and earlier, 6 Up

CVE-2025-49113 CRITICAL POC
9.9 Jun 02

Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au

CVE-2022-30333 HIGH POC
7.5 May 09

RARLAB UnRAR before 6.12 on Linux and UNIX allows directory traversal to write to files during an extract (aka unpack) o

CVE-2016-3714 HIGH POC
8.4 May 05

The (1) EPHEMERAL, (2) HTTPS, (3) MVG, (4) MSL, (5) TEXT, (6) SHOW, (7) WIN, and (8) PLT coders in ImageMagick before 6.

CVE-2017-12617 HIGH POC
8.1 Oct 04

When running Apache Tomcat versions 9.0.0.M1 to 9.0.0, 8.5.0 to 8.5.22, 8.0.0.RC1 to 8.0.46 and 7.0.0 to 7.0.81 with HTT

CVE-2020-1938 CRITICAL POC
9.8 Feb 24

When using the Apache JServ Protocol (AJP), care must be taken when trusting incoming connections to Apache Tomcat. Rate

CVE-2018-7602 CRITICAL POC
9.8 Jul 19

A remote code execution vulnerability exists within multiple subsystems of Drupal 7.x and 8.x. Rated critical severity (

Vendor StatusVendor

SUSE

Severity: Moderate
Product Status
Container suse/hpc/warewulf4-x86_64/sle-hpc-node:15.6.17.8.103 Image SLES15-SP6 Image SLES15-SP6-BYOS Image SLES15-SP6-BYOS-Azure Image SLES15-SP6-BYOS-EC2 Image SLES15-SP6-BYOS-GCE Image SLES15-SP6-CHOST-BYOS Image SLES15-SP6-CHOST-BYOS-Aliyun Image SLES15-SP6-CHOST-BYOS-Azure Image SLES15-SP6-CHOST-BYOS-EC2 Image SLES15-SP6-CHOST-BYOS-GCE Image SLES15-SP6-CHOST-BYOS-GDC Image SLES15-SP6-CHOST-BYOS-SAP-CCloud Image SLES15-SP6-EC2 Image SLES15-SP6-EC2-ECS-HVM Image SLES15-SP6-GCE Image SLES15-SP6-HPC-BYOS Image SLES15-SP6-HPC-BYOS-Azure Image SLES15-SP6-HPC-BYOS-EC2 Image SLES15-SP6-HPC-BYOS-GCE Image SLES15-SP6-HPC-EC2 Image SLES15-SP6-HPC-GCE Image SLES15-SP6-Hardened-BYOS Image SLES15-SP6-Hardened-BYOS-Azure Image SLES15-SP6-Hardened-BYOS-EC2 Image SLES15-SP6-Hardened-BYOS-GCE Image SLES15-SP6-SAP Image SLES15-SP6-SAP-Azure Image SLES15-SP6-SAP-EC2 Image SLES15-SP6-SAP-GCE Image SLES15-SP6-SAPCAL Image SLES15-SP6-SAPCAL-Azure Image SLES15-SP6-SAPCAL-EC2 Image SLES15-SP6-SAPCAL-GCE Affected
Container suse/sl-micro/6.0/base-os-container:2.1.3-7.44 Container suse/sl-micro/6.1/base-os-container:2.2.1-5.27 Image SL-Micro Image SL-Micro-Azure Image SL-Micro-BYOS-Azure Image SL-Micro-BYOS-EC2 Image SL-Micro-BYOS-GCE Image SL-Micro-EC2 Image SLE-Micro Image SLE-Micro-Azure Image SLE-Micro-BYOS Image SLE-Micro-BYOS-Azure Image SLE-Micro-BYOS-EC2 Image SLE-Micro-BYOS-GCE Image SLE-Micro-EC2 Image SLE-Micro-GCE Image SUSE-Multi-Linux-Manager-Proxy-BYOS-Azure Image SUSE-Multi-Linux-Manager-Proxy-BYOS-EC2 Image SUSE-Multi-Linux-Manager-Proxy-BYOS-GCE Image SUSE-Multi-Linux-Manager-Server-Azure-llc Image SUSE-Multi-Linux-Manager-Server-Azure-ltd Image SUSE-Multi-Linux-Manager-Server-BYOS-Azure Image SUSE-Multi-Linux-Manager-Server-BYOS-EC2 Image SUSE-Multi-Linux-Manager-Server-BYOS-GCE Image SUSE-Multi-Linux-Manager-Server-EC2-llc Image SUSE-Multi-Linux-Manager-Server-EC2-ltd Affected
Container suse/sl-micro/6.0/kvm-os-container:2.1.3-6.67 Container suse/sl-micro/6.1/kvm-os-container:2.2.1-5.29 Affected
Container suse/sl-micro/6.0/rt-os-container:2.1.3-7.76 Container suse/sl-micro/6.1/rt-os-container:2.2.1-5.14 Affected
Image SLES-Azure-3P Image SLES-Azure-Basic Image SLES-Azure-Standard Image SLES-BYOS-Azure Image SLES-BYOS-EC2 Image SLES-BYOS-GCE Image SLES-CHOST-BYOS-Aliyun Image SLES-CHOST-BYOS-Azure Image SLES-CHOST-BYOS-EC2 Image SLES-CHOST-BYOS-GCE Image SLES-CHOST-BYOS-GDC Image SLES-CHOST-BYOS-SAP-CCloud Image SLES-EC2 Image SLES-EC2-ECS Image SLES-GCE Image SLES-GCE-3P Image SLES-Hardened-BYOS-Azure Image SLES-Hardened-BYOS-EC2 Image SLES-Hardened-BYOS-GCE Image SLES-SAPCAL-Azure Image SLES-SAPCAL-EC2 Image SLES-SAPCAL-GCE Affected

Share

CVE-2025-38365 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy