diff --git a/abseil-cpp.spec b/abseil-cpp.spec index 8be82acf48a0dbeb55275dce4b4ce00f6e1af059..6787851aac6efb74af93bff5e3170ab3fa225bff 100644 --- a/abseil-cpp.spec +++ b/abseil-cpp.spec @@ -6,7 +6,7 @@ Name: abseil-cpp Version: 20240722.0 -Release: 3 +Release: 4 Summary: C++ Common Libraries License: Apache-2.0 @@ -15,6 +15,7 @@ Source0: https://github.com/abseil/abseil-cpp/archive/%{version}/%{name}- Patch1: abseil-cpp-20210324.2-sw.patch Patch100: 0001-add-loongarch-suopport-for-abseil-cpp.patch +Patch101: backport-CVE-2025-0838.patch BuildRequires: cmake ninja-build BuildRequires: gcc-c++ @@ -160,6 +161,12 @@ Development headers for %{name} %{_libdir}/pkgconfig/*.pc %changelog +* Wed Feb 26 2025 xinghe - 20240722.0-4 +- Type:cves +- ID:CVE-2025-0838 +- SUG:NA +- DESC:fix CVE-2025-0838 + * Fri Feb 14 2025 xinghe - 20240722.0-3 - Type:bugfix - ID:NA diff --git a/backport-CVE-2025-0838.patch b/backport-CVE-2025-0838.patch new file mode 100644 index 0000000000000000000000000000000000000000..1706ef0b8ab049f4517724bb6704df197f77ff00 --- /dev/null +++ b/backport-CVE-2025-0838.patch @@ -0,0 +1,120 @@ +From eb12bb08c70a91f082937b40c663cb4ac848c53f Mon Sep 17 00:00:00 2001 +From: Derek Mauro +Date: Wed, 22 Jan 2025 15:09:38 -0500 +Subject: [PATCH] Fix potential integer overflow in hash container + create/resize + +The sized constructors, reserve(), and rehash() methods of +absl::{flat,node}_hash_{set,map} did not impose an upper bound on +their size argument. As a result, it was possible for a caller to pass +a very large size that would cause an integer overflow when computing +the size of the container's backing store. Subsequent accesses to the +container might then access out-of-bounds memory. + +The fix is in two parts: + +1) Update max_size() to return the maximum number of items that can be +stored in the container + +2) Validate the size arguments to the constructors, reserve(), and +rehash() methods, and abort the program when the argument is invalid + +We've looked at uses of these containers in Google codebases like +Chrome, and determined this vulnerability is likely to be difficult to +exploit. This is primarily because container sizes are rarely +attacker-controlled. + +The bug was discovered by Dmitry Vyukov . + +Conflict: remove MODULE.bazel absl/base/config.h +Reference: https://github.com/abseil/abseil-cpp/commit/eb12bb08c70a91f082937b40c663cb4ac848c53f +--- + MODULE.bazel | 2 +- + absl/base/config.h | 2 +- + absl/container/internal/raw_hash_set.h | 18 +++++++++++++++++- + absl/container/internal/raw_hash_set_test.cc | 8 ++++++++ + 4 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h +index d4fe8f5c21b..7934b88c3eb 100644 +--- a/absl/container/internal/raw_hash_set.h ++++ b/absl/container/internal/raw_hash_set.h +@@ -1208,6 +1208,9 @@ class RawHashSetLayout { + // Given the capacity of a table, computes the total size of the backing + // array. + size_t alloc_size(size_t slot_size) const { ++ ABSL_HARDENING_ASSERT( ++ slot_size <= ++ ((std::numeric_limits::max)() - slot_offset_) / capacity_); + return slot_offset_ + capacity_ * slot_size; + } + +@@ -1500,6 +1503,12 @@ inline size_t NormalizeCapacity(size_t n) { + return n ? ~size_t{} >> countl_zero(n) : 1; + } + ++template ++size_t MaxValidCapacity() { ++ return NormalizeCapacity((std::numeric_limits::max)() / 4 / ++ kSlotSize); ++} ++ + // General notes on capacity/growth methods below: + // - We use 7/8th as maximum load factor. For 16-wide groups, that gives an + // average of two empty slots per group. +@@ -2614,6 +2623,8 @@ class raw_hash_set { + : settings_(CommonFields::CreateDefault(), hash, eq, + alloc) { + if (bucket_count > (SooEnabled() ? SooCapacity() : 0)) { ++ ABSL_RAW_CHECK(bucket_count <= MaxValidCapacity(), ++ "Hash table size overflow"); + resize(NormalizeCapacity(bucket_count)); + } + } +@@ -2871,7 +2882,9 @@ class raw_hash_set { + ABSL_ASSUME(!kEnabled || cap >= kCapacity); + return cap; + } +- size_t max_size() const { return (std::numeric_limits::max)(); } ++ size_t max_size() const { ++ return CapacityToGrowth(MaxValidCapacity()); ++ } + + ABSL_ATTRIBUTE_REINITIALIZES void clear() { + // Iterating over this container is O(bucket_count()). When bucket_count() +@@ -3260,6 +3273,8 @@ class raw_hash_set { + auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size())); + // n == 0 unconditionally rehashes as per the standard. + if (n == 0 || m > cap) { ++ ABSL_RAW_CHECK(m <= MaxValidCapacity(), ++ "Hash table size overflow"); + resize(m); + + // This is after resize, to ensure that we have completed the allocation +@@ -3272,6 +3287,7 @@ class raw_hash_set { + const size_t max_size_before_growth = + is_soo() ? SooCapacity() : size() + growth_left(); + if (n > max_size_before_growth) { ++ ABSL_RAW_CHECK(n <= max_size(), "Hash table size overflow"); + size_t m = GrowthToLowerboundCapacity(n); + resize(NormalizeCapacity(m)); + +diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc +index f1257d4b850..1604afef01c 100644 +--- a/absl/container/internal/raw_hash_set_test.cc ++++ b/absl/container/internal/raw_hash_set_test.cc +@@ -3594,6 +3594,14 @@ TEST(Iterator, InconsistentHashEqFunctorsValidation) { + "hash/eq functors are inconsistent."); + } + ++TEST(Table, MaxSizeOverflow) { ++ size_t overflow = (std::numeric_limits::max)(); ++ EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow), "Hash table size overflow"); ++ IntTable t; ++ EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow), "Hash table size overflow"); ++ EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow), "Hash table size overflow"); ++} ++ + } // namespace + } // namespace container_internal + ABSL_NAMESPACE_END