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