[PATCH 0/4] ceph: bound untrusted MDS and monitor reply decoders

From: Michael Bommarito

Date: Thu Jun 04 2026 - 14:12:07 EST


The CephFS client decodes several variable-length fields from MDS and
monitor replies without checking the declared length against the bytes
actually present in the message. Each of the four sites below trusts a
32-bit or 64-bit length from the wire and then copies, advances over, or
loops on it. A malicious or compromised server (or, for the monitor map,
an on-path attacker on an unsigned messenger session) can drive an
out-of-bounds read or an unbounded loop in the client kernel. The fixes
add the missing ceph_decode_need()/ceph_decode_copy_safe() bound or an
explicit count cap, matching the idioms already used elsewhere in the
same decoders.

Patch 1 is the most serious: the over-read value is returned to user
space through getxattr(2), so it is a kernel-heap information leak
(AC:H, requires a user to read the attribute). Patches 2-4 are
out-of-bounds reads / an unbounded loop that crash or wedge the client
(denial of service, no information disclosure). For patch 3 the supplier
is the monitor, a more privileged cluster role than the MDS; it is
included as a hardening fix for the info_v 2/3 compatibility path.

All four were reproduced on x86_64 QEMU with CONFIG_KASAN=y by calling
the real decoder via an in-tree debugfs harness, and re-run with the
patch applied:

patch 1: stock - __build_xattrs() stores val_len=304 from a 256-byte
blob, then the getxattr memcpy is a slab-out-of-bounds read of
304 bytes; patched - decode returns -EIO, no value stored.
patch 2: stock - slab-out-of-bounds read of 512 bytes in
handle_session(); patched - the bound rejects the record.
patch 3: stock - slab-out-of-bounds read in ceph_mdsmap_decode();
patched - decode returns -EINVAL.
patch 4: stock - ceph_parse_deleg_inos() runs 1048640 iterations on a
crafted len; patched - returns -EIO before the loop.

Well-formed replies still decode in every case (valid xattr value,
in-range delegation, in-bounds export-target array). These bugs were
found with AI assistance and are reported on the public list
accordingly, especially since they are mostly about a malicious
trusted server.

Michael Bommarito (4):
ceph: bound xattr value length in __build_xattrs()
ceph: bound MDSCapAuth path and fs_name decode in handle_session()
ceph: bound num_export_targets array for mds info v2/v3
ceph: cap delegated inode count in ceph_parse_deleg_inos()

fs/ceph/mds_client.c | 22 ++++++++++++++++++++--
fs/ceph/mdsmap.c | 2 ++
fs/ceph/super.h | 9 +++++++++
fs/ceph/xattr.c | 1 +
4 files changed, 32 insertions(+), 2 deletions(-)


base-commit: f72c95f3a516d87483e225ae081a402a09fd0127
--
2.53.0