critical

CVE

CVE-2026-64600

CWE

CWE-362, CWE-367

Affected Surface

  • Linux kernels `4.11+` that still carry the vulnerable XFS reflink direct-I/O logic, with public stable metadata tracking fixed upstream lines at `6.12.96`, `6.18.39`, and `7.1.4`
  • Enterprise Linux distributions that commonly install XFS with `reflink=1` by default, including RHEL, CentOS Stream, Rocky, AlmaLinux, CloudLinux, and Oracle Linux `8`-`10`, plus Amazon Linux `2023`, Amazon Linux 2 AMIs from December 2022 onward, and Fedora Server `31+`
  • Debian, Ubuntu, SUSE, and other Linux systems where administrators explicitly selected XFS with `reflink=1` for the root or another sensitive filesystem
  • Developer workstations, CI runners, build agents, containers, and multi-tenant Linux hosts where a malicious package, compromised build step, or low-privilege service can first gain ordinary local code execution

CVE-2026-64600, branded RefluXFS, is the most important new Linux application-security story from the last three days because it gives an attacker a reliable bridge from ordinary local code execution to host root on common enterprise filesystems. The bug is local-only, but that still squarely matters to AppSec teams: a malicious npm package, a compromised PyPI wheel, a poisoned CI step, or a low-privilege shell from an application bug can all use a local kernel issue as the second stage that breaks the host boundary.

What makes this disclosure unusually important is how practical the public exploit path is. Qualys did not publish a vague “might corrupt memory” note. They showed that a user who can only read a protected file and write to a scratch file on the same reflink-enabled XFS filesystem can race the kernel’s copy-on-write path and land a direct on-disk overwrite into the original root-owned target.

What is affected

The affected project is the Linux kernel, specifically the XFS reflink direct-I/O path. Public vulnerability metadata now tracks the bug as introduced by the Linux 4.11 era XFS reflink work and corrected in upstream stable lines including 6.12.96, 6.18.39, and 7.1.4. Distribution backports matter more than raw version numbers, but those stable cut points are a useful anchor for triage.

You should think about exposure as a three-part predicate:

  1. the kernel still carries the vulnerable XFS logic;
  2. the filesystem is XFS with reflink=1;
  3. the same filesystem holds both a readable high-value target and a writable directory for an unprivileged user.

That third condition sounds narrow until you map it to default layouts. On a standard single-volume enterprise install, /var/tmp or another writable location often sits on the same root filesystem as /etc and /usr/bin, which is exactly the arrangement the published advisory relies on.

ConditionWhy it matters
Linux kernel still includes the vulnerable XFS reflink paththe race exists in the kernel, not in userland tooling
XFS superblock has reflink=1the exploit depends on shared extents and copy-on-write remapping
Attacker can read a root-owned target and write elsewhere on the same filesystemFICLONE only needs read access to the source and write access to the destination

The quickest configuration check is:

findmnt -no FSTYPE /
xfs_info / | rg 'reflink='

If / is XFS and xfs_info shows reflink=1, treat the host as exposed until vendor kernel backports prove otherwise.

Root cause: imap went stale after the kernel dropped ILOCK

The bug sits in the handoff between xfs_direct_write_iomap_begin() and the reflink allocation helpers. The pre-fix flow reads the file’s data-fork mapping into imap, then enters a helper that may drop and later re-acquire the inode lock:

error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap,
        &nimaps, 0);
...
/* may drop and re-acquire the ilock */
error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared);

Inside xfs_reflink_fill_cow_hole() and xfs_reflink_fill_delalloc(), the helper must allocate a transaction. That can block on log space, so it intentionally drops ILOCK first:

xfs_iunlock(ip, *lockmode);
...
error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write, dblocks,
        rblocks, false, &tp);
...
*lockmode = XFS_ILOCK_EXCL;
error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found);

The problem is that imap still describes the old physical block mapping captured before the lock drop. A racing O_DIRECT writer running under IOLOCK_SHARED can complete a full copy-on-write cycle during that window:

Thread A: read data-fork mapping -> imap = physical block X
Thread A: drop ILOCK while waiting for transaction space
Thread B: allocate new block Y, remap the clone from X -> Y, refcount(X) drops to 1
Thread A: re-check shared state using stale imap that still points at X
Thread A: sees "*shared = false" and submits in-place direct I/O to X

By the time Thread A writes, block X is no longer the attacker’s clone block. It is once again the original target’s block. That is the core exploit primitive.

The upstream fix is small, but it closes exactly the right gap

The upstream patch does not redesign XFS. It adds a sequence check around the lock cycle and re-samples the data-fork mapping if the inode’s data-fork sequence changed while ILOCK was dropped:

unsigned int seq_before = READ_ONCE(ip->i_df.if_seq);
...
if (seq_before != READ_ONCE(ip->i_df.if_seq)) {
        nimaps = 1;
        error = xfs_bmapi_read(ip, imap->br_startoff,
                        imap->br_blockcount, imap, &nimaps, 0);
        if (error)
                goto out_trans_cancel;
}

That exact logic was added to both xfs_reflink_fill_cow_hole() and xfs_reflink_fill_delalloc(). The security value is precise: the shared-state recheck and any later in-place direct-I/O operation now use the current data-fork mapping, not the stale block address captured before another writer finished its CoW transition.

This is the kind of kernel fix AppSec teams should pay attention to because it tells you what actually went wrong:

  • the bug is not “XFS reflink is dangerous” in the abstract;
  • the bug is stale mapping state surviving a lock cycle;
  • the exploitability comes from direct I/O trusting that stale mapping after another writer already changed ownership of the physical block.

Why reflink=1 turns ordinary read access into a root primitive

The exploit path depends on XFS reflink semantics. FICLONE or cp --reflink does not copy file contents immediately; it creates a second file that points at the same on-disk extents as the original and increments a refcount in XFS metadata.

That means an unprivileged user who can read /etc/passwd or a SUID-root binary can create a writable clone on the same filesystem without needing write permission on the original:

root-owned target file --reflink--> attacker-owned clone
shared physical block X
refcount(X) = 2

The published exploit then uses synchronized O_DIRECT writes against the attacker’s clone so that one writer completes the legitimate CoW remap to a new block Y, while another writer lands an in-place write on stale block X. Qualys’ advisory describes a 32-thread barrier-synchronized write pattern with background truncation and sync churn to widen the transaction-allocation window.

The practical outcome is worse than a crash:

  • the overwrite lands directly on disk;
  • the target inode metadata does not need to change;
  • the modification survives reboot;
  • there is no helpful kernel log output;
  • SUID mode bits on a modified binary can remain intact.

Qualys demonstrated the primitive against /etc/passwd and notes that the first block of a SUID-root binary is another realistic target. That is enough to classify the issue as host-root critical rather than just local file corruption.

Why this belongs in an AppSec research library

RefluXFS is exactly the sort of Linux issue that package-security teams should model as a privilege amplifier:

  • a malicious npm package gets code execution on a developer workstation;
  • a backdoored PyPI dependency lands on a self-hosted CI runner;
  • a compromised build step runs as an unprivileged local user;
  • a web application flaw yields a low-privilege shell on an XFS-backed host.

If the host kernel is still vulnerable, the attacker no longer needs another application bug to reach root. The kernel supplies the second half of the chain.

This is especially relevant for:

  • self-hosted CI runners;
  • shared developer workstations;
  • bastions and internal multi-user Linux boxes;
  • container hosts where a workload already has local execution and the filesystem layout matches the prerequisites.

Detection and scoping

Start with the running kernel and filesystem layout:

uname -r
findmnt -no TARGET,FSTYPE,OPTIONS /
xfs_info / | rg 'reflink='

Then check whether your vendor kernel changelog already backported the fix:

rpm -q --changelog kernel | rg 'CVE-2026-64600|xfs: resample the data fork mapping after cycling ILOCK'

apt changelog linux-image-$(uname -r) 2>/dev/null | \
  rg 'CVE-2026-64600|xfs: resample the data fork mapping after cycling ILOCK'

Treat version numbers carefully. A distribution may already have a safe backport even if uname -r does not look like one of the exact upstream stable versions above. Conversely, a host can have updated packages installed but still be exploitable until it boots the fixed kernel.

For exposure prioritization, ask:

  1. Can untrusted or semi-trusted code run locally?
  2. Is the host XFS with reflink=1?
  3. Does the same filesystem hold both writable scratch space and sensitive root-owned files?

If the answer is yes across the board, this should be an emergency patch candidate.

Remediation

Patch the kernel through your vendor channel and reboot into the fixed kernel. There is no meaningful runtime hardening switch that cleanly neutralizes the vulnerable path once the filesystem already exists with reflink=1.

The public advisory is explicit on the important operational points:

  • reflink is a superblock feature set at mkfs time, not a toggle you can safely flip on a live filesystem;
  • SELinux, seccomp, KASLR, SMEP, SMAP, and container boundaries do not reliably block the primitive;
  • the attack works below the layers most user-space controls monitor well.

In other words, do not talk yourself into a soft mitigation plan here. If a host fits the prerequisites and can run untrusted local code, move it to a fixed kernel and verify the reboot completed successfully.

From research to remediation

Check whether this pattern exists in your codebase

Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.

References