diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-07-24 13:22:41 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-07-24 13:22:41 -0700 |
| commit | dad0a87d79ff3e7e4ef35ebd588fe4f115329964 (patch) | |
| tree | b8f300e11060a7c917865a6ca80b74c12b7cc18b /net/ceph/osdmap.c | |
| parent | 981f4a2baaf15a15fd4a22d311f15d066e28833b (diff) | |
| parent | 5b602344a49e039e792ce5a8923bcc61412ee134 (diff) | |
| download | linux-dad0a87d79ff3e7e4ef35ebd588fe4f115329964.tar.gz linux-dad0a87d79ff3e7e4ef35ebd588fe4f115329964.tar.bz2 linux-dad0a87d79ff3e7e4ef35ebd588fe4f115329964.zip | |
Merge tag 'ceph-for-7.2-rc5' of https://github.com/ceph/ceph-client
Pull ceph fixes from Ilya Dryomov:
"A bunch of assorted fixes with the majority being hardening against
malformed input and invalid data scenarios that don't happen in real
deployments but can be utilized to trigger use-after-free and similar
issues, some error path leak fixups and two patches from Max to avoid
a potential hang in __ceph_get_caps() and unintended nesting of
current->journal_info while handling replies from the MDS.
All marked for stable"
* tag 'ceph-for-7.2-rc5' of https://github.com/ceph/ceph-client:
ceph: avoid fs reclaim while using current->journal_info
ceph: add owner/capability checks for CEPH_IOC_SET_LAYOUT*
ceph: fix hanging __ceph_get_caps() with stale mds_wanted
rbd: Reset positive result codes to zero in object map update path
libceph: bound pg_{temp,upmap,upmap_items} length to CEPH_PG_MAX_SIZE
libceph: refresh auth->authorizer_buf{,_len} after authorizer update
ceph: fix refcount leak in ceph_readdir()
libceph: guard missing CRUSH type name lookup
libceph: remove debugfs files before client teardown
libceph: bound get_version reply decode to front len
ceph: fix writeback_count leak in write_folio_nounlock()
libceph: fix two unsafe bare decodes in decode_lockers()
ceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()
libceph: Reject monmaps advertising zero monitors
libceph: reject zero bucket types in crush_decode
libceph: Fix multiplication overflow in decode_new_up_state_weight()
Diffstat (limited to 'net/ceph/osdmap.c')
| -rw-r--r-- | net/ceph/osdmap.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 8b5b0587a0cf..a4b0dd8672ec 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -518,6 +518,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end) ceph_decode_need(p, end, 4*sizeof(u32), bad); b->id = ceph_decode_32(p); b->type = ceph_decode_16(p); + if (b->type == 0) + goto bad; b->alg = ceph_decode_8(p); if (b->alg != alg) { b->alg = 0; @@ -1436,7 +1438,7 @@ static struct ceph_pg_mapping *__decode_pg_temp(void **p, void *end, ceph_decode_32_safe(p, end, len, e_inval); if (len == 0 && incremental) return NULL; /* new_pg_temp: [] to remove */ - if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / sizeof(u32)) + if (len > CEPH_PG_MAX_SIZE) return ERR_PTR(-EINVAL); ceph_decode_need(p, end, len * sizeof(u32), e_inval); @@ -1617,7 +1619,7 @@ static struct ceph_pg_mapping *__decode_pg_upmap_items(void **p, void *end, u32 len, i; ceph_decode_32_safe(p, end, len, e_inval); - if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / (2 * sizeof(u32))) + if (len > CEPH_PG_MAX_SIZE) return ERR_PTR(-EINVAL); ceph_decode_need(p, end, 2 * len * sizeof(u32), e_inval); @@ -1842,6 +1844,8 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, void *new_up_client; void *new_state; void *new_weight_end; + const u32 new_state_item_size = + sizeof(u32) + (struct_v >= 5 ? sizeof(u32) : sizeof(u8)); u32 len; int ret; int i; @@ -1862,7 +1866,8 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, new_state = *p; ceph_decode_32_safe(p, end, len, e_inval); - len *= sizeof(u32) + (struct_v >= 5 ? sizeof(u32) : sizeof(u8)); + if (check_mul_overflow(len, new_state_item_size, &len)) + goto e_inval; ceph_decode_need(p, end, len, e_inval); *p += len; @@ -3055,8 +3060,11 @@ static int get_immediate_parent(struct crush_map *c, int id, if (b->items[j] != id) continue; - *parent_type_id = b->type; type_cn = lookup_crush_name(&c->type_names, b->type); + if (WARN_ON_ONCE(!type_cn)) + continue; + + *parent_type_id = b->type; parent_loc->cl_type_name = type_cn->cn_name; parent_loc->cl_name = cn->cn_name; return b->id; |