From bd6ee7e78d857bff31b0bb23f0ee8d8737ffef8e Mon Sep 17 00:00:00 2001 From: "J. Eric Ivancich" Date: Thu, 5 Jan 2023 13:57:37 -0500 Subject: [PATCH] rgw: fix FP error when calculating enteries per bi shard When calculating how many entries per shard to request during an ordered bucket listing, we divide by the number of bucket index shards. If this value is 0, then a floating point exception is generated, crashing the RGW. This addresses the proximate issue by detecting the situation and returning an error rather than crashing. Signed-off-by: J. Eric Ivancich --- src/rgw/rgw_rados.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index c5e5d53a3df..15fbe3d0ab1 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -8534,9 +8534,16 @@ int RGWRados::cls_obj_set_bucket_tag_timeout(const DoutPrefixProvider *dpp, RGWB } +// returns 0 if there is an error in calculation uint32_t RGWRados::calc_ordered_bucket_list_per_shard(uint32_t num_entries, uint32_t num_shards) { + if (num_shards == 0) { + // we'll get a floating point exception since we divide by + // num_shards + return 0; + } + // We want to minimize the chances that when num_shards >> // num_entries that we return much fewer than num_entries to the // client. Given all the overhead of making a cls call to the osd, @@ -8618,6 +8625,13 @@ int RGWRados::cls_bucket_list_ordered(const DoutPrefixProvider *dpp, } const uint32_t shard_count = shard_oids.size(); + if (shard_count == 0) { + ldpp_dout(dpp, 0) << "ERROR: " << __func__ << + ": the bucket index shard count appears to be 0, " + "which is an illegal value" << dendl; + return -ERR_INVALID_BUCKET_STATE; + } + uint32_t num_entries_per_shard; if (expansion_factor == 0) { num_entries_per_shard = @@ -8632,6 +8646,13 @@ int RGWRados::cls_bucket_list_ordered(const DoutPrefixProvider *dpp, num_entries_per_shard = num_entries; } + if (num_entries_per_shard == 0) { + ldpp_dout(dpp, 0) << "ERROR: " << __func__ << + ": unable to calculate the number of entries to read from each " + "bucket index shard" << dendl; + return -ERR_INVALID_BUCKET_STATE; + } + ldpp_dout(dpp, 10) << __func__ << ": request from each of " << shard_count << " shard(s) for " << num_entries_per_shard << " entries to get " << -- 2.39.5