---
id: "CVE-2026-98975"
kind: "vulnerability"
aliases: ["CVE-2026-98975"]
title: "Linux kernel XFS: reflink flag handling lets writes corrupt shared file blocks"
severity: "unknown"
cvss: null
epss: 0.00209
exploited: false
status: "open"
category: "infrastructure"
products: []
ecosystems: []
tags: ["infrastructure", "kernel", "linux", "xfs"]
not_affected_if: []
published_at: "2026-10-23T13:17:19+00:00"
first_seen_at: "2026-10-23T21:57:33+00:00"
updated_at: "2026-10-25T12:38:50+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-98975", "first_seen_at": "2026-10-23T21:57:33+00:00"}, {"source": "epss", "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-98975", "first_seen_at": "2026-10-25T12:38:50+00:00"}]
---

# Linux kernel XFS: reflink flag handling lets writes corrupt shared file blocks

In the Linux kernel XFS filesystem, an exchange operation could clear the reflink flag while a file still shared blocks past its on-disk size. The next write to such a block happens in place instead of copy-on-write, which can corrupt the other file sharing that block.

_Summary, check and fix written by a model from the sources; labelled as such._

## Timeline

- 2026-10-23T21:57:33+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-98975
- 2026-10-25T12:38:50+00:00 epss https://api.first.org/data/v1/epss?cve=CVE-2026-98975

## From the sources

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

xfs: stop exchanging reflink flags when exchanging mappings

When an exchange covers both files from offset 0 to i_disk_size,
xmi_can_exchange_reflink_flags() assumes every mapping moved and hands
the reflink flag over to the other file.

That assumption is wrong.  A file can still own shared blocks past
i_disk_size, e.g. after EXCHANGE_RANGE_TO_EOF sets a smaller size
without unmapping anything.  The flag is cleared anyway, and the next
write to such a block happens in place instead of CoW, corrupting the
other file that shares it.

Commit a23eca88448e ("xfs: fix exchange-range reflink flag clearing
issue with INO1_WRITTEN") fixed one instance of this.  Rather than add
another special case, stop moving the flags.
xfs_exchmaps_ensure_reflink() already sets the flag on both inodes
before the exchange, so both just keep it.

Nothing sets CLEAR_INO{1,2}_REFLINK anymore.  Intents logged by older
kernels may still carry them; recovery already masks them off, so they
stay in the log format mask and are ignored.

XFS_IOC_SWAPEXT has the same problem: it moves the reflink flag from
one inode to the other along with the extents.  Just removing that is
not enough here: the exchange path flags both inodes up front in
xfs_exchmaps_ensure_reflink(), but swapext has no such step, so the
inode receiving the shared extents would be left without the flag.
Set it on both inodes instead, and make sure both have a CoW fork,
since an inode with the reflink flag is expected to have one.

The flag now stays until FALLOC_FL_UNSHARE_RANGE, xfs_scrub, or a
truncate to zero removes it.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
