From 10655007b9b679e46a9e383202c7bb791e5d1d13 Mon Sep 17 00:00:00 2001 From: Raphael Zimmer Date: Wed, 9 Sep 2026 17:03:53 +0200 Subject: [PATCH] libceph: Fix multiple unsafe decodes in ceph_oloc_decode() ceph_oloc_decode handles unchecked data received over the network from an OSD. Currently, there are multiple decode operations that aren't covered by any bounds check. Decoding these fields can therefore result in out-of-bounds reads if a corrupted message is received. This patch fixes the issue by adding bounds checks covering all previously uncovered decode operations. [ idryomov: use ceph_decode_64_safe() for hash ] Cc: stable@vger.kernel.org Fixes: 205ee1187a67 ("libceph: follow redirect replies from osds") Assisted-by: Cursor Signed-off-by: Raphael Zimmer Reviewed-by: Alex Markuze Signed-off-by: Ilya Dryomov --- net/ceph/osd_client.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 3f23027fba3c..b8e4740d07fe 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -3567,6 +3567,7 @@ static int ceph_oloc_decode(void **p, void *end, ceph_decode_need(p, end, len, e_inval); struct_end = *p + len; + ceph_decode_need(p, end, 8 + 4 + 4, e_inval); oloc->pool = ceph_decode_64(p); *p += 4; /* skip preferred */ @@ -3579,7 +3580,7 @@ static int ceph_oloc_decode(void **p, void *end, if (struct_v >= 5) { bool changed = false; - len = ceph_decode_32(p); + ceph_decode_32_safe(p, end, len, e_inval); if (len > 0) { ceph_decode_need(p, end, len, e_inval); if (!oloc->pool_ns || @@ -3598,7 +3599,9 @@ static int ceph_oloc_decode(void **p, void *end, } if (struct_v >= 6) { - s64 hash = ceph_decode_64(p); + s64 hash; + + ceph_decode_64_safe(p, end, hash, e_inval); if (hash != -1) { pr_warn("ceph_object_locator::hash is set\n"); goto e_inval;