Re: [PATCH v3] libceph: Reject monmaps advertising zero monitors

Ilya Dryomov <[email protected]> Wed, 22 Jul 2026 22:48:57 +0200
Newsgroups org.kernel.vger.ceph-devel
Message-ID <CAOi1vP_M=S4ob92+tR9f+9foNPX9rFjZqZJFyzLaF5xRdSq2Gw@mail.gmail.com>
On Fri, May 29, 2026 at 9:43 AM Raphael Zimmer
<[email protected]> wrote:
>
> A message of type CEPH_MSG_MON_MAP contains a monmap that is sent from a
> monitor to the client. This monmap contains information about the
> existing monitors in the cluster. Currently, a monmap indicating that
> there are zero monitors in the cluster is treated as valid. However, it
> is impossible to have zero monitors in the cluster and still receive a
> valid monmap from a monitor. Therefore, such a monmap must be corrupted
> and should be treated as invalid. Furthermore, a monmap with a monitor
> count of zero can subsequently crash the client when attempting to open
> a session with a monitor in __open_session(). This happens because the
> "BUG_ON(monc->monmap->num_mon < 1)" assertion in pick_new_mon() is
> triggered.
>
> This patch extends a check in ceph_monmap_decode() to also reject
> arriving mon_maps with num_mon == 0 rather than only with
> num_mon > CEPH_MAX_MON. Additionally, a log output is added for unusual
> values of num_mon.
>
> Signed-off-by: Raphael Zimmer <[email protected]>
> ---
>  net/ceph/mon_client.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
> index d2cdc8ee3155..33eb4baa5a10 100644
> --- a/net/ceph/mon_client.c
> +++ b/net/ceph/mon_client.c
> @@ -114,9 +114,13 @@ static struct ceph_monmap *ceph_monmap_decode(void **p, void *end, bool msgr2)
>
>         dout("%s fsid %pU epoch %u num_mon %u\n", __func__, &fsid, epoch,
>              num_mon);
> -       if (num_mon > CEPH_MAX_MON)
> +       if (num_mon == 0 || num_mon > CEPH_MAX_MON)
>                 goto e_inval;
>
> +       if (num_mon == 1 || (num_mon & 1) == 0)
> +               pr_notice_ratelimited("received monmap with unusual num_mon %u\n",
> +                                     num_mon);
> +
>         monmap = kmalloc_flex(*monmap, mon_inst, num_mon, GFP_NOIO);
>         if (!monmap) {
>                 ret = -ENOMEM;
> --
> 2.47.3
>

Hi Raphael,

I have staged this patch without the "Additionally, a log output is
added for unusual values of num_mon" bit (so essentially v1 with the
order of num_mon checks reversed as suggested by Slava).  Many toy or
short-lived development setups have just one monitor and in general
I don't think the client has any business second guessing the cluster
operator's decisions as to the number of monitors or anything similar
such as OSD failure domains, etc.  Zero monitors is clearly invalid,
anything else (up to CEPH_MAX_MON) the client can digest.

Thanks,

                Ilya