CVE-2026-89649
Critical · 9.1CVSS
9.1
EPSS
0.7%
Published
Sep 11, 2026
CISA due date
—
Cloudanix analysis
A bug in how Linux handles file metadata from Ceph storage servers can let a local user read secret data from inside the operating system's own memory.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- Other
- Complexity
- Low
- Impact
- Data Exposure
- Component
- OS kernel
- Class
- Information Disclosure
- Remediation
- Patch
- Effort
- Medium
- Patch risk
- Low
What it actually does
Missing bounds check on the final xattr value length in __build_xattrs() allows a malicious MDS to supply an oversized len, causing __set_xattr() to store the invalid length and a later getxattr(2) to perform memcpy() past the end of the kvmalloc() blob, disclosing adjacent kernel heap to userspace.
Why it matters to the business
Local users on CephFS clients can read arbitrary adjacent kernel memory, enabling credential or secret leakage that may lead to further compromise; urgent for organizations running CephFS with untrusted or externally hosted metadata servers.
How an attack unfolds
An attacker who controls or has compromised the Ceph MDS crafts an xattr blob where the last attribute's value length exceeds the actual buffer; when the client decodes it, the oversized length is stored verbatim; a subsequent getxattr syscall triggers an out-of-bounds memcpy that returns kernel heap contents to the attacker-controlled user buffer.
How to fix it
Apply the upstream kernel patch that adds the missing ceph_decode_need() check before advancing over the final xattr value; upgrade to a kernel release containing the fix for CVE-2026-89649; until patched, restrict getxattr usage on CephFS mounts or isolate CephFS clients from untrusted MDS instances.
How to confirm the fix worked
Confirm the patched kernel is running; attempt to trigger the original decode path with a crafted final xattr and verify that -EIO is returned instead of a successful oversized memcpy; review CephFS client logs for decode failures on xattr blobs.
Typical attack path
- Compromise or control the Ceph metadata server
- Inject a specially crafted xattr blob containing an oversized final value length
- Wait for or trigger client inode population via ceph_fill_inode()
- Perform getxattr(2) on a CephFS file to trigger the oversized memcpy
- Receive leaked kernel heap bytes in the returned buffer
How to detect it
Search kernel logs and audit trails for Ceph xattr decode errors (EIO) during inode population; inspect getxattr calls returning unexpectedly large data; correlate with MDS communication anomalies or unusual xattr blob sizes on the wire.
- ceph_decode_need.*xattr
- EIO.*__build_xattrs
- oversized xattr value length
What your security team should do
- Immediately prioritize kernel upgrades for all CephFS client nodes
- Audit Ceph deployments for any externally hosted or multi-tenant MDS instances
- Add monitoring for unexpected -EIO returns from xattr decode paths
- Limit unprivileged getxattr access on CephFS where feasible until patches are applied
The record
In the Linux kernel, the following vulnerability has been resolved: ceph: bound xattr value length in __build_xattrs() __build_xattrs() decodes the MDS-supplied xattr blob one attribute at a time. For each attribute it reads a 32-bit name length, advances past the name bytes, reads a 32-bit value length, records the value pointer, and advances past the value bytes. The two length fields are read with ceph_decode_32_safe(), but the value bytes themselves are advanced over with a bare "p += len" and no ceph_decode_need() check that "len" bytes remain in the blob. For every attribute except the last, the next iteration's ceph_decode_32_safe() on the following name length implicitly verifies that the previous value did not run past the blob end. The final attribute has no successor, so its decoded value length is never checked against the blob bounds. A malicious or compromised metadata server can set the last attribute's value length larger than the bytes actually present in the blob. The blob is a dedicated kvmalloc() allocation sized to the wire length (ceph_buffer_new() in ceph_fill_inode()). __set_xattr() records the oversized length in xattr->val_len verbatim, and a later getxattr(2) runs memcpy(value, xattr->val, xattr->val_len) into a user-supplied buffer, copying bytes past the end of the allocation back to user space. Impact: a malicious metadata server discloses adjacent kernel heap bytes to a local user via getxattr(2) on a CephFS file. Add the missing ceph_decode_need() so an out-of-bounds value length on the final attribute fails the decode and returns -EIO instead of being stored.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|