diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index cf34b35c9a90..7bd27c2fc872 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -376,7 +376,9 @@ static int decode_choose_args(void **p, void *end, struct crush_map *c) ceph_decode_32_safe(p, end, num_buckets, e_inval); while (num_buckets--) { struct crush_choose_arg *arg; + struct crush_bucket *bucket; u32 bucket_index; + u32 i; ceph_decode_32_safe(p, end, bucket_index, e_inval); if (bucket_index >= arg_map->size) @@ -387,10 +389,18 @@ static int decode_choose_args(void **p, void *end, struct crush_map *c) if (ret) goto fail; + bucket = c->buckets[bucket_index]; if (arg->ids_size && - (!c->buckets[bucket_index] || - arg->ids_size != c->buckets[bucket_index]->size)) + (!bucket || arg->ids_size != bucket->size)) goto e_inval; + + if (arg->weight_set_size && !bucket) + goto e_inval; + + for (i = 0; i < arg->weight_set_size; i++) { + if (arg->weight_set[i].size != bucket->size) + goto e_inval; + } } if (!__insert_choose_arg_map(&c->choose_args, arg_map)) {