Skip to content

Commit 5de4ce3

Browse files
[AutoPR- Security] Patch abseil-cpp for CVE-2025-0838 [MEDIUM] (#15780)
Co-authored-by: akhila-guruju <v-guakhila@microsoft.com>
1 parent 3d5a030 commit 5de4ce3

File tree

2 files changed

+183
-1
lines changed

2 files changed

+183
-1
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
From 5a0e2cb5e3958dd90bb8569a2766622cb74d90c1 Mon Sep 17 00:00:00 2001
2+
From: Derek Mauro <dmauro@google.com>
3+
Date: Thu, 23 Jan 2025 06:33:43 -0800
4+
Subject: [PATCH] Fix potential integer overflow in hash container
5+
create/resize
6+
7+
The sized constructors, reserve(), and rehash() methods of
8+
absl::{flat,node}_hash_{set,map} did not impose an upper bound on
9+
their size argument. As a result, it was possible for a caller to pass
10+
a very large size that would cause an integer overflow when computing
11+
the size of the container's backing store. Subsequent accesses to the
12+
container might then access out-of-bounds memory.
13+
14+
The fix is in two parts:
15+
16+
1) Update max_size() to return the maximum number of items that can be
17+
stored in the container
18+
19+
2) Validate the size arguments to the constructors, reserve(), and
20+
rehash() methods, and abort the program when the argument is invalid
21+
22+
We've looked at uses of these containers in Google codebases like
23+
Chrome, and determined this vulnerability is likely to be difficult to
24+
exploit. This is primarily because container sizes are rarely
25+
attacker-controlled.
26+
27+
The bug was discovered by Dmitry Vyukov <dvyukov@google.com>.
28+
29+
PiperOrigin-RevId: 718841870
30+
Change-Id: Ic09dc9de140a35dbb45ab9d90f58383cf2de8286
31+
32+
Upstream Patch reference: https://github.com/abseil/abseil-cpp/commit/5a0e2cb5e3958dd90bb8569a2766622cb74d90c1.patch
33+
---
34+
absl/container/internal/raw_hash_set.cc | 5 +++
35+
absl/container/internal/raw_hash_set.h | 36 +++++++++++++++++++-
36+
absl/container/internal/raw_hash_set_test.cc | 8 +++++
37+
3 files changed, 48 insertions(+), 1 deletion(-)
38+
39+
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
40+
index c63a2e0..0f0b9d6 100644
41+
--- a/absl/container/internal/raw_hash_set.cc
42+
+++ b/absl/container/internal/raw_hash_set.cc
43+
@@ -18,6 +18,7 @@
44+
#include <cstddef>
45+
46+
#include "absl/base/config.h"
47+
+#include "absl/base/internal/raw_logging.h"
48+
49+
namespace absl {
50+
ABSL_NAMESPACE_BEGIN
51+
@@ -66,6 +67,10 @@ void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) {
52+
// Extern template instantiotion for inline function.
53+
template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t);
54+
55+
+void HashTableSizeOverflow() {
56+
+ ABSL_RAW_LOG(FATAL, "Hash table size overflow");
57+
+}
58+
+
59+
} // namespace container_internal
60+
ABSL_NAMESPACE_END
61+
} // namespace absl
62+
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
63+
index ea912f8..05d4f14 100644
64+
--- a/absl/container/internal/raw_hash_set.h
65+
+++ b/absl/container/internal/raw_hash_set.h
66+
@@ -219,6 +219,15 @@ namespace absl {
67+
ABSL_NAMESPACE_BEGIN
68+
namespace container_internal {
69+
70+
+#ifdef ABSL_SWISSTABLE_ASSERT
71+
+#error ABSL_SWISSTABLE_ASSERT cannot be directly set
72+
+#else
73+
+// We use this macro for assertions that users may see when the table is in an
74+
+// invalid state that sanitizers may help diagnose.
75+
+#define ABSL_SWISSTABLE_ASSERT(CONDITION) \
76+
+ assert((CONDITION) && "Try enabling sanitizers.")
77+
+#endif
78+
+
79+
template <typename AllocType>
80+
void SwapAlloc(AllocType& lhs, AllocType& rhs,
81+
std::true_type /* propagate_on_container_swap */) {
82+
@@ -745,6 +754,15 @@ inline size_t NormalizeCapacity(size_t n) {
83+
return n ? ~size_t{} >> countl_zero(n) : 1;
84+
}
85+
86+
+template <size_t kSlotSize>
87+
+size_t MaxValidCapacity() {
88+
+ return NormalizeCapacity((std::numeric_limits<size_t>::max)() / 4 /
89+
+ kSlotSize);
90+
+}
91+
+
92+
+// Use a non-inlined function to avoid code bloat.
93+
+[[noreturn]] void HashTableSizeOverflow();
94+
+
95+
// General notes on capacity/growth methods below:
96+
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
97+
// average of two empty slots per group.
98+
@@ -913,6 +931,9 @@ inline size_t SlotOffset(size_t capacity, size_t slot_align) {
99+
// Given the capacity of a table, computes the total size of the backing
100+
// array.
101+
inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) {
102+
+ ABSL_SWISSTABLE_ASSERT(
103+
+ slot_size <=
104+
+ ((std::numeric_limits<size_t>::max)() - SlotOffset(capacity, slot_align)) / capacity);
105+
return SlotOffset(capacity, slot_align) + capacity * slot_size;
106+
}
107+
108+
@@ -1148,6 +1169,10 @@ class raw_hash_set {
109+
: ctrl_(EmptyGroup()),
110+
settings_(0, HashtablezInfoHandle(), hash, eq, alloc) {
111+
if (bucket_count) {
112+
+ if (ABSL_PREDICT_FALSE(bucket_count >
113+
+ MaxValidCapacity<sizeof(slot_type)>())) {
114+
+ HashTableSizeOverflow();
115+
+ }
116+
capacity_ = NormalizeCapacity(bucket_count);
117+
initialize_slots();
118+
}
119+
@@ -1341,7 +1366,9 @@ class raw_hash_set {
120+
bool empty() const { return !size(); }
121+
size_t size() const { return size_; }
122+
size_t capacity() const { return capacity_; }
123+
- size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }
124+
+ size_t max_size() const {
125+
+ return CapacityToGrowth(MaxValidCapacity<sizeof(slot_type)>());
126+
+ }
127+
128+
ABSL_ATTRIBUTE_REINITIALIZES void clear() {
129+
// Iterating over this container is O(bucket_count()). When bucket_count()
130+
@@ -1678,6 +1705,9 @@ class raw_hash_set {
131+
auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size()));
132+
// n == 0 unconditionally rehashes as per the standard.
133+
if (n == 0 || m > capacity_) {
134+
+ if (ABSL_PREDICT_FALSE(m > MaxValidCapacity<sizeof(slot_type)>())) {
135+
+ HashTableSizeOverflow();
136+
+ }
137+
resize(m);
138+
139+
// This is after resize, to ensure that we have completed the allocation
140+
@@ -1688,6 +1718,9 @@ class raw_hash_set {
141+
142+
void reserve(size_t n) {
143+
if (n > size() + growth_left()) {
144+
+ if (ABSL_PREDICT_FALSE(n > max_size())) {
145+
+ HashTableSizeOverflow();
146+
+ }
147+
size_t m = GrowthToLowerboundCapacity(n);
148+
resize(NormalizeCapacity(m));
149+
150+
@@ -2361,5 +2394,6 @@ ABSL_NAMESPACE_END
151+
} // namespace absl
152+
153+
#undef ABSL_INTERNAL_ASSERT_IS_FULL
154+
+#undef ABSL_SWISSTABLE_ASSERT
155+
156+
#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
157+
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
158+
index f77ffbc..078bbad 100644
159+
--- a/absl/container/internal/raw_hash_set_test.cc
160+
+++ b/absl/container/internal/raw_hash_set_test.cc
161+
@@ -2181,6 +2181,14 @@ TEST(Table, AlignOne) {
162+
}
163+
}
164+
165+
+TEST(Table, MaxSizeOverflow) {
166+
+ size_t overflow = (std::numeric_limits<size_t>::max)();
167+
+ EXPECT_DEATH_IF_SUPPORTED(IntTable t(overflow), "Hash table size overflow");
168+
+ IntTable t;
169+
+ EXPECT_DEATH_IF_SUPPORTED(t.reserve(overflow), "Hash table size overflow");
170+
+ EXPECT_DEATH_IF_SUPPORTED(t.rehash(overflow), "Hash table size overflow");
171+
+}
172+
+
173+
} // namespace
174+
} // namespace container_internal
175+
ABSL_NAMESPACE_END
176+
--
177+
2.43.0
178+

SPECS/abseil-cpp/abseil-cpp.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
Summary: C++ Common Libraries
22
Name: abseil-cpp
33
Version: 20220623.0
4-
Release: 1%{?dist}
4+
Release: 2%{?dist}
55
License: ASL 2.0
66
Vendor: Microsoft Corporation
77
Distribution: Mariner
88
URL: https://abseil.io
99
Source0: https://github.com/abseil/abseil-cpp/archive/%{version}/%{name}-%{version}.tar.gz
10+
Patch0: CVE-2025-0838.patch
1011

1112
BuildRequires: cmake >= 3.20.0
1213
BuildRequires: gcc
@@ -81,6 +82,9 @@ ctest --output-on-failure
8182
%{_libdir}/pkgconfig/*.pc
8283

8384
%changelog
85+
* Tue Feb 10 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 20220623.0-2
86+
- Patch for CVE-2025-0838
87+
8488
* Thu Jun 30 2022 Pawel Winogrodzki <pawelwi@microsoft.com> - 20220623.0-1
8589
- Updating to 20220623.0 to remove workaround patches for GTest.
8690

0 commit comments

Comments
 (0)