Re: [PATCH v3] libceph: Fix multiplication overflow in __decode_pg_upmap_items()
Ilya Dryomov <[email protected]> Thu, 23 Jul 2026 22:41:31 +0200
| Newsgroups | org.kernel.vger.ceph-devel |
|---|---|
| Message-ID | <CAOi1vP_6WjqQp-7a_g6g=U9100cW54G-1jSjWRH3ieh4u9u-bA@mail.gmail.com> |
On Tue, May 19, 2026 at 1:01 PM Raphael Zimmer <[email protected]> wrote: > > A message of type CEPH_MSG_OSD_MAP holds an OSD map, which typically > contains a pg_upmap part at its end. When decoding this part in > __decode_pg_upmap_items(), a len value is decoded from the message to > determine the number of items and the size of the allocation needed for > them. If the len value is greater than or equal to 2^31, an overflow > occurs in the multiplication that is performed to determine the needed > size of the incoming buffer to decode, as well as for the length of the > allocation for the ceph_pg_mapping struct. Subsequently, this results in > out-of-bounds writes (and reads) when decoding the incoming message > fields into the ceph_pg_mapping struct. > > This patch fixes the issue by splitting the computation into multiple > parts and storing the results in local variables of type size_t. This > prevents the overflow by performing the multiplication in the > appropriate data type and ensures that the result is calculated only > once. > > Signed-off-by: Raphael Zimmer <[email protected]> > --- > net/ceph/osdmap.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c > index 8b5b0587a0cf..076763420b1d 100644 > --- a/net/ceph/osdmap.c > +++ b/net/ceph/osdmap.c > @@ -1615,13 +1615,16 @@ static struct ceph_pg_mapping *__decode_pg_upmap_items(void **p, void *end, > { > struct ceph_pg_mapping *pg; > u32 len, i; > + const size_t item_size = 2 * sizeof(u32); > + size_t payload_len; > > ceph_decode_32_safe(p, end, len, e_inval); > - if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / (2 * sizeof(u32))) > + if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / item_size) Hi Raphael, I think this can be just len > CEPH_PG_MAX_SIZE. I have folded the corresponding fixup into someone else's patch that originally did that only for __decode_pg_temp(): https://github.com/ceph/ceph-client/commit/9f00f9cf2be293efe899db67dc5272e3a9c62717 If you agree, we can retire this patch. Thanks, Ilya