diff mbox series

[kirkstone,meta-oe] abseil-cpp: fix CVE-2025-0838

Message ID 20250227063650.2696429-1-changqing.li@windriver.com
State New
Headers show
Series [kirkstone,meta-oe] abseil-cpp: fix CVE-2025-0838 | expand

Commit Message

Changqing Li Feb. 27, 2025, 6:36 a.m. UTC
From: Changqing Li <changqing.li@windriver.com>

Backport a patch to fix CVE-2025-0838

CVE-2025-0838:
There exists a heap buffer overflow vulnerable in Abseil-cpp. 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, and a subsequent out-of-bounds memory
write. Subsequent accesses to the container might also access
out-of-bounds memory. We recommend upgrading past commit
5a0e2cb5e3958dd90bb8569a2766622cb74d90c1

Reference:
https://nvd.nist.gov/vuln/detail/CVE-2025-0838

Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
 .../abseil-cpp/abseil-cpp/CVE-2025-0838.patch | 114 ++++++++++++++++++
 .../abseil-cpp/abseil-cpp_git.bb              |   1 +
 2 files changed, 115 insertions(+)
 create mode 100644 meta-oe/recipes-devtools/abseil-cpp/abseil-cpp/CVE-2025-0838.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp/CVE-2025-0838.patch b/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp/CVE-2025-0838.patch
new file mode 100644
index 0000000000..c8d5cd1f0a
--- /dev/null
+++ b/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp/CVE-2025-0838.patch
@@ -0,0 +1,114 @@ 
+From bdbad523d92cd2308139086226bfc36fc2068267 Mon Sep 17 00:00:00 2001
+From: Changqing Li <changqing.li@windriver.com>
+Date: Thu, 27 Feb 2025 12:05:11 +0800
+Subject: [PATCH] Fix potential integer overflow in hash container
+ create/resize (#1813)
+
+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 <dvyukov@google.com>.
+
+CVE: CVE-2025-0838
+Upstream-Status: Backport [https://github.com/abseil/abseil-cpp/commit/caa7bb4457bfcafcd55a940204ef78c1bf1f417d]
+This patch is backported from 20230802.3
+
+Signed-off-by: Changqing Li <changqing.li@windriver.com>
+---
+ absl/container/internal/raw_hash_set.h       | 15 ++++++++++++++-
+ absl/container/internal/raw_hash_set_test.cc |  8 ++++++++
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
+index 046a6939..ecea25b4 100644
+--- a/absl/container/internal/raw_hash_set.h
++++ b/absl/container/internal/raw_hash_set.h
+@@ -662,6 +662,12 @@ inline size_t NormalizeCapacity(size_t n) {
+   return n ? ~size_t{} >> countl_zero(n) : 1;
+ }
+ 
++template <size_t kSlotSize>
++size_t MaxValidCapacity() {
++  return NormalizeCapacity((std::numeric_limits<size_t>::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.
+@@ -1065,6 +1071,8 @@ class raw_hash_set {
+       : ctrl_(EmptyGroup()),
+         settings_(0, HashtablezInfoHandle(), hash, eq, alloc) {
+     if (bucket_count) {
++      ABSL_RAW_CHECK(bucket_count <= MaxValidCapacity<sizeof(slot_type)>(),
++                     "Hash table size overflow");
+       capacity_ = NormalizeCapacity(bucket_count);
+       initialize_slots();
+     }
+@@ -1258,7 +1266,9 @@ class raw_hash_set {
+   bool empty() const { return !size(); }
+   size_t size() const { return size_; }
+   size_t capacity() const { return capacity_; }
+-  size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }
++  size_t max_size() const {
++    return CapacityToGrowth(MaxValidCapacity<sizeof(slot_type)>());
++  }
+ 
+   ABSL_ATTRIBUTE_REINITIALIZES void clear() {
+     // Iterating over this container is O(bucket_count()). When bucket_count()
+@@ -1595,6 +1605,8 @@ class raw_hash_set {
+     auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
+     // n == 0 unconditionally rehashes as per the standard.
+     if (n == 0 || m > capacity_) {
++      ABSL_RAW_CHECK(m <= MaxValidCapacity<sizeof(slot_type)>(),
++                     "Hash table size overflow");
+       resize(m);
+ 
+       // This is after resize, to ensure that we have completed the allocation
+@@ -1605,6 +1617,7 @@ class raw_hash_set {
+ 
+   void reserve(size_t n) {
+     if (n > size() + growth_left()) {
++      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 9cd88a28..81a5c866 100644
+--- a/absl/container/internal/raw_hash_set_test.cc
++++ b/absl/container/internal/raw_hash_set_test.cc
+@@ -2176,6 +2176,14 @@ TEST(Table, AlignOne) {
+   }
+ }
+ 
++TEST(Table, MaxSizeOverflow) {
++  size_t overflow = (std::numeric_limits<size_t>::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
+-- 
+2.34.1
+
diff --git a/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp_git.bb b/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp_git.bb
index 30eef75ffb..dd63aedab9 100644
--- a/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp_git.bb
+++ b/meta-oe/recipes-devtools/abseil-cpp/abseil-cpp_git.bb
@@ -15,6 +15,7 @@  SRC_URI = "git://github.com/abseil/abseil-cpp;branch=${BRANCH};protocol=https \
            file://0002-Remove-maes-option-from-cross-compilation.patch \
            file://abseil-ppc-fixes.patch \
            file://0001-absl-strings-internal-str_format-extension.h-add-mis.patch \
+           file://CVE-2025-0838.patch \
           "
 
 S = "${WORKDIR}/git"