]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rocksdb: upgrade submodule to v7.10.2 to address CVE-2022-23476 69106/head
authorKefu Chai <k.chai@proxmox.com>
Thu, 28 May 2026 11:11:24 +0000 (19:11 +0800)
committerKefu Chai <k.chai@proxmox.com>
Fri, 29 May 2026 01:55:35 +0000 (09:55 +0800)
This commit upgrades the rocksdb submodule from v7.9.2 to v7.10.2 to
address CVE-2022-23476, a security vulnerability in the Nokogiri gem
used by RocksDB's documentation build system.

CVE-2022-23476 Details:
- Affects: RocksDB versions < 7.10.2
- Issue: Unchecked return value from xmlTextReaderExpand in Nokogiri
- Fix commit: 6648dec0a3eee0a329af8342038ce099baa55122
- Fixed in: Nokogiri 1.13.10, included in RocksDB v7.10.2

The vulnerability was fixed in the upstream facebook/rocksdb repository
on December 8, 2022, and included in the v7.10.2 release. The v7.9.2
version currently used by Ceph does not contain this fix, as the 7.9.x
branch diverged before the security patch was applied.

Analysis confirmed that:
- Current Ceph RocksDB: v7.9.2 (commit 24ea35870fe9b3ba15285ec8746ba97ed5d67ff3)
- CVE fix present in v7.9.2: NO
- First version with fix: v7.10.2 (commit 9107c1059b4656513ae0d51e8976e4f69f59a9c3)

References:
- CVE-2022-23476: https://nvd.nist.gov/vuln/detail/CVE-2022-23476
- Nokogiri Advisory: GHSA-qv4q-mr5r-qprj
- Fix commit: facebook/rocksdb@6648dec

also, in this change, we adapt BinnedLRUCache to CacheItemHelper API.
rocksdb 7.10 reshaped `rocksdb::Cache`, so we have to update our
overrides accordingly to address the build failure. the check for
RocksDB version is dropped, as mainstream distros ship RocksDB >=
7.10.2 at the time of writing:

- alpine 3.23:    10.9.1
- fedora 44:      10.2.1
- debian stable:   9.10.0
- ubuntu nobel:    8.9.1
- ubuntu resolute: 9.11.2

Signed-off-by: Justin Caratzas <jcaratza@ibm.com>
Signed-off-by: Kefu Chai <k.chai@proxmox.com>
src/kv/rocksdb_cache/BinnedLRUCache.cc
src/kv/rocksdb_cache/BinnedLRUCache.h
src/kv/rocksdb_cache/ShardedCache.cc
src/kv/rocksdb_cache/ShardedCache.h
src/rocksdb

index b2344032f1d03c5a9250539bebfd28fdb9d492f8..be51b0325a9f958e49e297d50d28b7fa443553af 100644 (file)
@@ -160,9 +160,9 @@ void BinnedLRUCacheShard::EraseUnRefEntries() {
 
 void BinnedLRUCacheShard::ApplyToAllCacheEntries(
   const std::function<void(const rocksdb::Slice& key,
-                           void* value,
+                           rocksdb::Cache::ObjectPtr value,
                            size_t charge,
-                           DeleterFn)>& callback,
+                           const rocksdb::Cache::CacheItemHelper* helper)>& callback,
   bool thread_safe)
 {
   if (thread_safe) {
@@ -170,7 +170,7 @@ void BinnedLRUCacheShard::ApplyToAllCacheEntries(
   }
   table_.ApplyToAllCacheEntries(
     [callback](BinnedLRUHandle* h) {
-      callback(h->key(), h->value, h->charge, h->deleter);
+      callback(h->key(), h->value, h->charge, h->helper);
     });
   if (thread_safe) {
     mutex_.unlock();
@@ -419,16 +419,17 @@ bool BinnedLRUCacheShard::Release(rocksdb::Cache::Handle* handle, bool force_era
   return last_reference;
 }
 
-rocksdb::Status BinnedLRUCacheShard::Insert(const rocksdb::Slice& key, uint32_t hash, void* value,
+rocksdb::Status BinnedLRUCacheShard::Insert(const rocksdb::Slice& key, uint32_t hash,
+                             rocksdb::Cache::ObjectPtr value,
+                             const rocksdb::Cache::CacheItemHelper* helper,
                              size_t charge,
-                             DeleterFn deleter,
                              rocksdb::Cache::Handle** handle, rocksdb::Cache::Priority priority) {
   auto e = new BinnedLRUHandle();
   rocksdb::Status s;
   BinnedLRUHandle* deleted = nullptr;
 
   e->value = value;
-  e->deleter = deleter;
+  e->helper = helper;
   e->charge = charge;
   e->key_length = key.size();
   e->key_data = new char[e->key_length];
@@ -560,10 +561,11 @@ std::string BinnedLRUCacheShard::GetPrintableOptions() const {
   return std::string(buffer);
 }
 
-DeleterFn BinnedLRUCacheShard::GetDeleter(rocksdb::Cache::Handle* h) const
+const rocksdb::Cache::CacheItemHelper*
+BinnedLRUCacheShard::GetCacheItemHelper(rocksdb::Cache::Handle* h) const
 {
   auto* handle = reinterpret_cast<BinnedLRUHandle*>(h);
-  return handle->deleter;
+  return handle->helper;
 }
 
 #undef dout_context
@@ -702,7 +704,7 @@ const CacheShard* BinnedLRUCache::GetShard(int shard) const {
   return reinterpret_cast<CacheShard*>(&shards_[shard]);
 }
 
-void* BinnedLRUCache::Value(Handle* handle) {
+rocksdb::Cache::ObjectPtr BinnedLRUCache::Value(Handle* handle) {
   return reinterpret_cast<const BinnedLRUHandle*>(handle)->value;
 }
 
@@ -721,12 +723,11 @@ void BinnedLRUCache::DisownData() {
 #endif  // !__SANITIZE_ADDRESS__
 }
 
-#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22))
-DeleterFn BinnedLRUCache::GetDeleter(Handle* handle) const
+const rocksdb::Cache::CacheItemHelper*
+BinnedLRUCache::GetCacheItemHelper(Handle* handle) const
 {
-  return reinterpret_cast<const BinnedLRUHandle*>(handle)->deleter;
+  return reinterpret_cast<const BinnedLRUHandle*>(handle)->helper;
 }
-#endif
 
 size_t BinnedLRUCache::TEST_GetLRUSize() {
   size_t lru_size_of_all_shards = 0;
index a419154c27734af87eb589db2fcc02f247b9f36b..44392e7d4bc2562c570a03e248d29b798f284226 100644 (file)
@@ -58,8 +58,8 @@ std::shared_ptr<rocksdb::Cache> NewBinnedLRUCache(
 
 struct BinnedLRUHandle {
   std::shared_ptr<uint64_t> age_bin;
-  void* value;
-  DeleterFn deleter;
+  rocksdb::Cache::ObjectPtr value;
+  const rocksdb::Cache::CacheItemHelper* helper;
   BinnedLRUHandle* next_hash;
   BinnedLRUHandle* next;
   BinnedLRUHandle* prev;
@@ -121,8 +121,8 @@ struct BinnedLRUHandle {
 
   void Free() {
     ceph_assert((refs == 1 && InCache()) || (refs == 0 && !InCache()));
-    if (deleter) {
-      (*deleter)(key(), value);
+    if (helper && helper->del_cb) {
+      (*helper->del_cb)(value, /*allocator=*/nullptr);
     }
     delete[] key_data;
     delete this;
@@ -240,9 +240,10 @@ class alignas(CACHE_LINE_SIZE) BinnedLRUCacheShard : public CacheShard {
   void SetHighPriPoolRatio(double high_pri_pool_ratio);
 
   // Like Cache methods, but with an extra "hash" parameter.
-  virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash, void* value,
+  virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash,
+                        rocksdb::Cache::ObjectPtr value,
+                        const rocksdb::Cache::CacheItemHelper* helper,
                         size_t charge,
-                        DeleterFn deleter,
                         rocksdb::Cache::Handle** handle,
                         rocksdb::Cache::Priority priority) override;
   virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, uint32_t hash) override;
@@ -260,16 +261,17 @@ class alignas(CACHE_LINE_SIZE) BinnedLRUCacheShard : public CacheShard {
 
   virtual void ApplyToAllCacheEntries(
     const std::function<void(const rocksdb::Slice& key,
-                             void* value,
+                             rocksdb::Cache::ObjectPtr value,
                              size_t charge,
-                             DeleterFn)>& callback,
+                             const rocksdb::Cache::CacheItemHelper* helper)>& callback,
     bool thread_safe) override;
 
   virtual void EraseUnRefEntries() override;
 
   virtual std::string GetPrintableOptions() const override;
 
-  virtual DeleterFn GetDeleter(rocksdb::Cache::Handle* handle) const override;
+  virtual const rocksdb::Cache::CacheItemHelper* GetCacheItemHelper(
+      rocksdb::Cache::Handle* handle) const override;
 
   void TEST_GetLRUList(BinnedLRUHandle** lru, BinnedLRUHandle** lru_low_pri);
 
@@ -382,13 +384,12 @@ class BinnedLRUCache : public ShardedCache {
   virtual const char* Name() const override { return "BinnedLRUCache"; }
   virtual CacheShard* GetShard(int shard) override;
   virtual const CacheShard* GetShard(int shard) const override;
-  virtual void* Value(Handle* handle) override;
+  virtual rocksdb::Cache::ObjectPtr Value(Handle* handle) override;
   virtual size_t GetCharge(Handle* handle) const override;
   virtual uint32_t GetHash(Handle* handle) const override;
   virtual void DisownData() override;
-#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22))
-  virtual DeleterFn GetDeleter(Handle* handle) const override;
-#endif
+  virtual const rocksdb::Cache::CacheItemHelper* GetCacheItemHelper(
+      Handle* handle) const override;
   //  Retrieves number of elements in LRU, for unit test purpose only
   size_t TEST_GetLRUSize();
   // Sets the high pri pool ratio
index 7d160f9c7b427bd084e51143c2ce34bb98fe3009..b6fcb01174f62f934827f26510682afffe64501b 100644 (file)
@@ -43,15 +43,23 @@ void ShardedCache::SetStrictCapacityLimit(bool strict_capacity_limit) {
   strict_capacity_limit_ = strict_capacity_limit;
 }
 
-rocksdb::Status ShardedCache::Insert(const rocksdb::Slice& key, void* value, size_t charge,
-                            DeleterFn deleter,
+rocksdb::Status ShardedCache::Insert(const rocksdb::Slice& key,
+                            rocksdb::Cache::ObjectPtr value,
+                            const rocksdb::Cache::CacheItemHelper* helper,
+                            size_t charge,
                             rocksdb::Cache::Handle** handle, Priority priority) {
   uint32_t hash = HashSlice(key);
   return GetShard(Shard(hash))
-      ->Insert(key, hash, value, charge, deleter, handle, priority);
+      ->Insert(key, hash, value, helper, charge, handle, priority);
 }
 
-rocksdb::Cache::Handle* ShardedCache::Lookup(const rocksdb::Slice& key, rocksdb::Statistics* /*stats*/) {
+rocksdb::Cache::Handle* ShardedCache::Lookup(const rocksdb::Slice& key,
+                            const rocksdb::Cache::CacheItemHelper* /*helper*/,
+                            rocksdb::Cache::CreateContext* /*create_context*/,
+                            Priority /*priority*/, bool /*wait*/,
+                            rocksdb::Statistics* /*stats*/) {
+  // Secondary cache is not supported by BinnedLRUCache, so the helper,
+  // create_context, priority, wait, and stats arguments are ignored here.
   uint32_t hash = HashSlice(key);
   return GetShard(Shard(hash))->Lookup(key, hash);
 }
@@ -109,36 +117,25 @@ size_t ShardedCache::GetPinnedUsage() const {
   return usage;
 }
 
-#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22))
-DeleterFn ShardedCache::GetDeleter(Handle* handle) const
+const rocksdb::Cache::CacheItemHelper* ShardedCache::GetCacheItemHelper(
+    Handle* handle) const
 {
   uint32_t hash = GetHash(handle);
-  return GetShard(Shard(hash))->GetDeleter(handle);
+  return GetShard(Shard(hash))->GetCacheItemHelper(handle);
 }
 
 void ShardedCache::ApplyToAllEntries(
-    const std::function<void(const rocksdb::Slice& key, void* value, size_t charge,
-                             DeleterFn deleter)>& callback,
-    const ApplyToAllEntriesOptions& opts)
+    const std::function<void(const rocksdb::Slice& key,
+                             rocksdb::Cache::ObjectPtr value,
+                             size_t charge,
+                             const rocksdb::Cache::CacheItemHelper* helper)>& callback,
+    const ApplyToAllEntriesOptions& /*opts*/)
 {
   int num_shards = 1 << num_shard_bits_;
   for (int s = 0; s < num_shards; s++) {
     GetShard(s)->ApplyToAllCacheEntries(callback, true /* thread_safe */);
   }
 }
-#else
-void ShardedCache::ApplyToAllCacheEntries(void (*callback)(void*, size_t),
-                                          bool thread_safe) {
-  int num_shards = 1 << num_shard_bits_;
-  for (int s = 0; s < num_shards; s++) {
-    GetShard(s)->ApplyToAllCacheEntries(
-      [callback](const rocksdb::Slice&, void* value, size_t charge, DeleterFn) {
-        callback(value, charge);
-      },
-      thread_safe);
-  }
-}
-#endif
 
 void ShardedCache::EraseUnRefEntries() {
   int num_shards = 1 << num_shard_bits_;
index 63a56c4577eb1d1d8d81f849bc36f3d964792ddf..8a78ddbf08de05d5d29502cf872333b3f7053b33 100644 (file)
 
 namespace rocksdb_cache {
 
-using DeleterFn = void (*)(const rocksdb::Slice& key, void* value);
-
 // Single cache shard interface.
 class CacheShard {
  public:
   CacheShard() = default;
   virtual ~CacheShard() = default;
 
-  virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash, void* value,
+  virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash,
+                                 rocksdb::Cache::ObjectPtr value,
+                                 const rocksdb::Cache::CacheItemHelper* helper,
                                  size_t charge,
-                                 DeleterFn deleter,
-                                 rocksdb::Cache::Handle** handle, rocksdb::Cache::Priority priority) = 0;
+                                 rocksdb::Cache::Handle** handle,
+                                 rocksdb::Cache::Priority priority) = 0;
   virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, uint32_t hash) = 0;
   virtual bool Ref(rocksdb::Cache::Handle* handle) = 0;
   virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) = 0;
@@ -48,13 +48,14 @@ class CacheShard {
   virtual size_t GetPinnedUsage() const = 0;
   virtual void ApplyToAllCacheEntries(
     const std::function<void(const rocksdb::Slice& key,
-                             void* value,
+                             rocksdb::Cache::ObjectPtr value,
                              size_t charge,
-                             DeleterFn)>& callback,
+                             const rocksdb::Cache::CacheItemHelper* helper)>& callback,
     bool thread_safe) = 0;
   virtual void EraseUnRefEntries() = 0;
   virtual std::string GetPrintableOptions() const { return ""; }
-  virtual DeleterFn GetDeleter(rocksdb::Cache::Handle* handle) const = 0;
+  virtual const rocksdb::Cache::CacheItemHelper* GetCacheItemHelper(
+      rocksdb::Cache::Handle* handle) const = 0;
 };
 
 // Generic cache interface which shards cache by hash of keys. 2^num_shard_bits
@@ -67,15 +68,22 @@ class ShardedCache : public rocksdb::Cache, public PriorityCache::PriCache {
   // rocksdb::Cache
   virtual const char* Name() const override = 0;
   using rocksdb::Cache::Insert;
-  virtual rocksdb::Status Insert(const rocksdb::Slice& key, void* value, size_t charge,
-                                 DeleterFn,
-                                 rocksdb::Cache::Handle** handle, Priority priority) override;
+  virtual rocksdb::Status Insert(const rocksdb::Slice& key,
+                                 rocksdb::Cache::ObjectPtr value,
+                                 const rocksdb::Cache::CacheItemHelper* helper,
+                                 size_t charge,
+                                 rocksdb::Cache::Handle** handle,
+                                 Priority priority) override;
   using rocksdb::Cache::Lookup;
-  virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, rocksdb::Statistics* stats) override;
+  virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key,
+                                         const rocksdb::Cache::CacheItemHelper* helper,
+                                         rocksdb::Cache::CreateContext* create_context,
+                                         Priority priority, bool wait,
+                                         rocksdb::Statistics* stats) override;
   virtual bool Ref(rocksdb::Cache::Handle* handle) override;
   using rocksdb::Cache::Release;
   virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) override;
-  virtual void* Value(Handle* handle) override = 0;
+  virtual rocksdb::Cache::ObjectPtr Value(Handle* handle) override = 0;
   virtual void Erase(const rocksdb::Slice& key) override;
   virtual uint64_t NewId() override;
   virtual void SetCapacity(size_t capacity) override;
@@ -85,20 +93,16 @@ class ShardedCache : public rocksdb::Cache, public PriorityCache::PriCache {
   virtual size_t GetUsage() const override;
   virtual size_t GetUsage(rocksdb::Cache::Handle* handle) const override;
   virtual size_t GetPinnedUsage() const override;
-  virtual size_t GetCharge(Handle* handle) const = 0;
-#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22))
-  virtual DeleterFn GetDeleter(Handle* handle) const override;
-#endif
+  virtual size_t GetCharge(Handle* handle) const override = 0;
+  virtual const rocksdb::Cache::CacheItemHelper* GetCacheItemHelper(
+      Handle* handle) const override;
   virtual void DisownData() override = 0;
-#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22))
   virtual void ApplyToAllEntries(
-      const std::function<void(const rocksdb::Slice& key, void* value, size_t charge,
-                               DeleterFn deleter)>& callback,
+      const std::function<void(const rocksdb::Slice& key,
+                               rocksdb::Cache::ObjectPtr value,
+                               size_t charge,
+                               const rocksdb::Cache::CacheItemHelper* helper)>& callback,
       const ApplyToAllEntriesOptions& opts) override;
-#else
-  virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t),
-                                      bool thread_safe) override;
-#endif
   virtual void EraseUnRefEntries() override;
   virtual std::string GetPrintableOptions() const override;
   virtual CacheShard* GetShard(int shard) = 0;
index 24ea35870fe9b3ba15285ec8746ba97ed5d67ff3..0bd97e703ec62ad602717482508b08dd91baa8f5 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 24ea35870fe9b3ba15285ec8746ba97ed5d67ff3
+Subproject commit 0bd97e703ec62ad602717482508b08dd91baa8f5