From: Kefu Chai Date: Thu, 28 May 2026 11:11:24 +0000 (+0800) Subject: rocksdb: upgrade submodule to v7.10.2 to address CVE-2022-23476 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=43dd4cbd370455590d12337f09138a7f7b635bd9;p=ceph.git rocksdb: upgrade submodule to v7.10.2 to address CVE-2022-23476 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 Signed-off-by: Kefu Chai --- diff --git a/src/kv/rocksdb_cache/BinnedLRUCache.cc b/src/kv/rocksdb_cache/BinnedLRUCache.cc index b2344032f1d..be51b0325a9 100644 --- a/src/kv/rocksdb_cache/BinnedLRUCache.cc +++ b/src/kv/rocksdb_cache/BinnedLRUCache.cc @@ -160,9 +160,9 @@ void BinnedLRUCacheShard::EraseUnRefEntries() { void BinnedLRUCacheShard::ApplyToAllCacheEntries( const std::function& 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(h); - return handle->deleter; + return handle->helper; } #undef dout_context @@ -702,7 +704,7 @@ const CacheShard* BinnedLRUCache::GetShard(int shard) const { return reinterpret_cast(&shards_[shard]); } -void* BinnedLRUCache::Value(Handle* handle) { +rocksdb::Cache::ObjectPtr BinnedLRUCache::Value(Handle* handle) { return reinterpret_cast(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(handle)->deleter; + return reinterpret_cast(handle)->helper; } -#endif size_t BinnedLRUCache::TEST_GetLRUSize() { size_t lru_size_of_all_shards = 0; diff --git a/src/kv/rocksdb_cache/BinnedLRUCache.h b/src/kv/rocksdb_cache/BinnedLRUCache.h index a419154c277..44392e7d4bc 100644 --- a/src/kv/rocksdb_cache/BinnedLRUCache.h +++ b/src/kv/rocksdb_cache/BinnedLRUCache.h @@ -58,8 +58,8 @@ std::shared_ptr NewBinnedLRUCache( struct BinnedLRUHandle { std::shared_ptr 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& 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 diff --git a/src/kv/rocksdb_cache/ShardedCache.cc b/src/kv/rocksdb_cache/ShardedCache.cc index 7d160f9c7b4..b6fcb01174f 100644 --- a/src/kv/rocksdb_cache/ShardedCache.cc +++ b/src/kv/rocksdb_cache/ShardedCache.cc @@ -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& callback, - const ApplyToAllEntriesOptions& opts) + const std::function& 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_; diff --git a/src/kv/rocksdb_cache/ShardedCache.h b/src/kv/rocksdb_cache/ShardedCache.h index 63a56c4577e..8a78ddbf08d 100644 --- a/src/kv/rocksdb_cache/ShardedCache.h +++ b/src/kv/rocksdb_cache/ShardedCache.h @@ -26,18 +26,18 @@ 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& 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& callback, + const std::function& 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; diff --git a/src/rocksdb b/src/rocksdb index 24ea35870fe..0bd97e703ec 160000 --- a/src/rocksdb +++ b/src/rocksdb @@ -1 +1 @@ -Subproject commit 24ea35870fe9b3ba15285ec8746ba97ed5d67ff3 +Subproject commit 0bd97e703ec62ad602717482508b08dd91baa8f5