CVE-2026-98975
High · 7.8CVSS
7.8
EPSS
0.2%
Published
Oct 23, 2026
CISA due date
—
Cloudanix analysis
A flaw in how the Linux kernel handles certain file operations on shared data blocks can cause unexpected data corruption.
- Exploitation
- Local Privilege
- Attacker needs
- Low Privilege
- Complexity
- Low
- Impact
- Data Tampering
- Component
- OS kernel
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Medium
What it actually does
Incorrect transfer or clearing of XFS reflink flags during extent exchange or swapext operations can leave inodes without the flag while still sharing blocks, causing subsequent writes to modify shared blocks in place instead of triggering copy-on-write.
Why it matters to the business
Organizations using XFS filesystems with reflink-enabled files risk silent data corruption that can affect multiple files sharing extents, leading to integrity loss and potential operational disruption on affected systems.
How an attack unfolds
An attacker with local access to an XFS filesystem creates or manipulates files sharing blocks beyond i_disk_size, then triggers exchange-range or XFS_IOC_SWAPEXT operations so that the receiving inode loses its reflink flag; subsequent writes then corrupt the shared data visible to the other file.
How to fix it
Update the Linux kernel to a version containing the fix that stops reflink flag exchange and ensures both inodes retain the flag plus a CoW fork; apply vendor kernel updates as they become available.
How to confirm the fix worked
Confirm the running kernel includes the described change (stop moving CLEAR_INO{1,2}_REFLINK and pre-setting reflink flags on both inodes); test reflink exchange behavior on files with shared blocks past EOF to verify the flag is preserved.
Typical attack path
- Obtain local user access on a system using XFS with reflinks
- Arrange files that share blocks past logical EOF via prior reflink operations
- Invoke XFS_IOC_EXCHANGE_RANGE or XFS_IOC_SWAPEXT covering the shared region
- Perform writes to the affected blocks on the inode that lost the reflink flag
- Observe or leverage resulting corruption in the other sharing file
How to detect it
Inspect kernel logs for XFS exchange or swapext operations on reflinked files, and look for unexpected data changes in files known to share blocks; no public exploit artifacts are known.
What your security team should do
- Prioritize kernel updates on all systems using XFS reflinks
- Review and restrict local access to XFS volumes containing critical shared data until patched
- Monitor for XFS-related kernel updates from distributions
The record
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.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|