Re: [PATCH v3] libceph: Avoid using invalid osd indices from primary_temp
Ilya Dryomov <[email protected]> Wed, 29 Jul 2026 09:43:50 +0200
| Newsgroups | org.kernel.vger.ceph-devel |
|---|---|
| Message-ID | <CAOi1vP_f4xpgu2AKoVCQ48RZH7Aj9VqehUsuUMs0tuW-iqDFwQ@mail.gmail.com> |
On Tue, Jul 28, 2026 at 10:44=E2=80=AFAM Raphael Zimmer <[email protected]> wrote: > > 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. Hi Raphael, pg_temp and primary_temp are orthogonal -- it's valid for the PG to have a primary_temp entry but not a pg_temp entry so it would be more precise to say "... the primary from pg_temp or the up set ..." here. > > Fixes: 63244fa123a7 ("libceph: introduce ceph_osd_request_target, calc_ta= rget()") Even though the backport that far wouldn't be clean (and wouldn't happen regardless), the potential for a bogus primary_temp entry to be enacted came with support for primary_temp in commit 5e8d4d36bf23 ("libceph: add support for primary_temp mappings"). > 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 *osdm= ap, > } > } > > - /* primary_temp? */ > + /* primary_temp? (shouldn't ever be a nonexistent or down OSD) */ > pg =3D 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 =3D pg->primary_temp.osd; > } > > -- > 2.47.3 > Applied with the above fixups to the changelog. Thanks, Ilya