]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: prevent crash in `radosgw-admin bucket object shard ...` 62884/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 18:18:32 +0000 (14:18 -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>
(cherry picked from commit a2b76b0e09ece61fd0978411d08d13257fe6ddbe)

src/rgw/driver/rados/rgw_tools.h
src/rgw/rgw_admin.cc
src/rgw/services/svc_bi_rados.h

index 9f5a1ae1a424979a3de9e92c377bb318608b2ee7..8bfe5b5aee11f8797ce4794dbd5d9509d65cdc10 100644 (file)
@@ -45,10 +45,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 620f124ef43b7a2f1f208b6b3eac600cf1e573e8..70875a17b5f9e3a172f648af2f23ace944c34c9c 100644 (file)
@@ -7474,8 +7474,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 c6c11f8bc00b9590be902eba26f2a17191785017..d9fc3dd65a3ad48e0298e55b211df214ac0d904c 100644 (file)
@@ -99,15 +99,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) {