Re: [PATCH v3] libceph: Fix multiplication overflow in __decode_pg_upmap_items()
Raphael Zimmer <[email protected]> Mon, 27 Jul 2026 10:47:23 +0200
| Newsgroups | org.kernel.vger.ceph-devel |
|---|---|
| Message-ID | <[email protected]> |
On 23.07.26 10:41 PM, Ilya Dryomov wrote: > 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 Hi Ilya, this solution with "len > CEPH_PG_MAX_SIZE" will equally solve the issue. Therefore, I'm fine with doing it this way. Best regards, Raphael