]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: `radosgw-admin bucket stats` on indexless bucket crashes
authorJ. Eric Ivancich <ivancich@redhat.com>
Thu, 23 Dec 2021 21:25:26 +0000 (16:25 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 27 May 2022 19:47:33 +0000 (15:47 -0400)
The new bucket layout code didn't check whether the bucket is
indexless prior to asking for the last entry in the layout log. The
layout log appears to be empty for an indexless bucket, thereby
putting the runtime in an undefined state that later may cause a
failed assertion.

This commit adds two safety checks and returns -EINVAL along with
putting useful information on stderr when either stats are requested
on an indexless bucket or when the layout log is empty.

Signed-off-by: J. Eric Ivancich <ivancich@redhat.com>
src/rgw/rgw_bucket.cc

index 7405d0919adbc229bfd5b8acff74b3ff5ebcce2e..8f231c9780dadcd102bdf629706b17eda760439f 100644 (file)
@@ -1044,10 +1044,25 @@ static int bucket_stats(rgw::sal::Store* store,
     return ret;
   }
 
-  string bucket_ver, master_ver;
-  string max_marker;
+  if (bucket->get_info().layout.current_index.layout.type ==
+      rgw::BucketIndexType::Indexless) {
+    cerr << "error, indexless buckets do not maintain stats; bucket=" <<
+      bucket->get_name() << std::endl;
+    return -EINVAL;
+  }
+
+  if (bucket->get_info().layout.logs.empty()) {
+    // this check may be redundant with the previous check of
+    // layout.type; calling back() on an empty vector produces
+    // undefined behavior
+    cerr << "error, layout log list is empty; bucket=" << bucket->get_name() <<
+      std::endl;
+    return -EINVAL;
+  }
   const auto& latest_log = bucket->get_info().layout.logs.back();
   const auto& index = log_to_index_layout(latest_log);
+  std::string bucket_ver, master_ver;
+  std::string max_marker;
   ret = bucket->read_stats(dpp, index, RGW_NO_SHARD, &bucket_ver, &master_ver, stats, &max_marker);
   if (ret < 0) {
     cerr << "error getting bucket stats bucket=" << bucket->get_name() << " ret=" << ret << std::endl;