[PATCH v3] libceph: Avoid using invalid osd indices from primary_temp

Raphael Zimmer <[email protected]> Tue, 28 Jul 2026 10:43:40 +0200
Newsgroups org.kernel.vger.ceph-devel
Message-ID <[email protected]>
A corrupted osdmap received from a Ceph monitor or OSD may contain osd
indices in its pg_temp, primary_temp, pg_upmap, and pg_upmap_items parts
that don't exist, i.e., that are greater than max_osd or smaller than
CEPH_HOMELESS_OSD (-1). These indices are used to create the up and
acting set in ceph_pg_to_up_acting_osds(), called from calc_target().
While most of these osd indices are checked, the one from primary_temp
is not. Subsequently, this may lead to calc_target() returning this
(potentially invalid) index as target osd for a (linger) request.
Because the osd_state, osd_weight, and osd_addr arrays only contain
max_osd entries (with indices 0 to max_osd -1), this leads to
out-of-bounds accesses when trying to read values from these arrays.

This patch fixes the issue by adding a check to get_temp_osds(), so that
only valid osd indices from primary_temp are used, and it falls back to
using the primary from pg_temp if it is invalid.

Fixes: 63244fa123a7 ("libceph: introduce ceph_osd_request_target, calc_target()")
Signed-off-by: Raphael Zimmer <[email protected]>
---
 net/ceph/osdmap.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index ed58a03b2f5d..5565de128bce 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -2815,9 +2815,10 @@ static void get_temp_osds(struct ceph_osdmap *osdmap,
 		}
 	}
 
-	/* primary_temp? */
+	/* primary_temp? (shouldn't ever be a nonexistent or down OSD) */
 	pg = lookup_pg_mapping(&osdmap->primary_temp, pgid);
-	if (pg)
+	if (pg && !WARN_ON_ONCE(ceph_osd_is_down(osdmap,
+						 pg->primary_temp.osd)))
 		temp->primary = pg->primary_temp.osd;
 }
 
-- 
2.47.3