]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: prevent crash in `radosgw-admin bucket object shard ...` 62850/head
authorJ. Eric Ivancich <ivancich@redhat.com>
Wed, 16 Apr 2025 16:38:33 +0000 (12:38 -0400)
committerJ. Eric Ivancich <ivancich@redhat.com>
Fri, 18 Apr 2025 13:25:35 +0000 (09:25 -0400)
This subcommand is used to ask radosgw-admin which bucket index shard
a given object in a given bucket would have its bucket index entry
on. The user is required to supply the number of shards (i.e., the
command doesn't look that up). If 0 is provided it would result in a
divide by zero runtime exception. Values less than or equal to zero
are now protected.

Signed-off-by: J. Eric Ivancich <ivancich@redhat.com>
src/rgw/driver/rados/rgw_tools.h
src/rgw/radosgw-admin/radosgw-admin.cc
src/rgw/services/svc_bi_rados.h

index 3f3cd628507f4349b9bbbe9f6d443b666b077531..c18892c4cca4a15dbaca2ee835f0a3528471d12d 100644 (file)
@@ -62,10 +62,13 @@ inline int rgw_shards_max()
 // only called by rgw_shard_id and rgw_bucket_shard_index
 static inline int rgw_shards_mod(unsigned hval, int max_shards)
 {
-  if (max_shards <= RGW_SHARDS_PRIME_0) {
+  if (max_shards <= 0) {
+    return -1;
+  } else if (max_shards <= RGW_SHARDS_PRIME_0) {
     return hval % RGW_SHARDS_PRIME_0 % max_shards;
+  } else {
+    return hval % RGW_SHARDS_PRIME_1 % max_shards;
   }
-  return hval % RGW_SHARDS_PRIME_1 % max_shards;
 }
 
 // used for logging and tagging
index febd03846848f113397786716d5025d634997999..d3b5aa7fb75293619d8e0e4119a68b1bef5c5c27 100644 (file)
@@ -7695,8 +7695,13 @@ int main(int argc, const char **argv)
       cerr << "ERROR: num-shards and object must be specified."
           << std::endl;
       return EINVAL;
+    } else if (num_shards <= 0) {
+      cerr << "ERROR: non-positive value supplied for num-shards: " <<
+       num_shards << std::endl;
+      return EINVAL;
     }
-    auto shard = RGWSI_BucketIndex_RADOS::bucket_shard_index(object, num_shards);
+    auto shard =
+      RGWSI_BucketIndex_RADOS::bucket_shard_index(object, num_shards);
     formatter->open_object_section("obj_shard");
     encode_json("shard", shard, formatter.get());
     formatter->close_section();
index 2103c1c08a16d50b5ca94b82439795b3bbd8dd02..e2b978d61ca855e967c206c984a1d2f9cc5c37ce 100644 (file)
@@ -100,15 +100,15 @@ public:
     return rgw_shard_id(key, max_shards);
   }
 
-  static uint32_t bucket_shard_index(const std::string& key,
-                                     int num_shards) {
+  static int32_t bucket_shard_index(const std::string& key,
+                                   int num_shards) {
     uint32_t sid = ceph_str_hash_linux(key.c_str(), key.size());
     uint32_t sid2 = sid ^ ((sid & 0xFF) << 24);
     return rgw_shards_mod(sid2, num_shards);
   }
 
-  static uint32_t bucket_shard_index(const rgw_obj_key& obj_key,
-                                    int num_shards)
+  static int32_t bucket_shard_index(const rgw_obj_key& obj_key,
+                                   int num_shards)
   {
     std::string sharding_key;
     if (obj_key.ns == RGW_OBJ_NS_MULTIPART) {