Skip to content

Commit 1c56ad8

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

2 files changed

Lines changed: 183 additions & 1 deletion

File tree

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 9f8ea51..fc704d6 100644
41+
--- a/absl/container/internal/raw_hash_set.cc
42+
+++ b/absl/container/internal/raw_hash_set.cc
43+
@@ -22,6 +22,7 @@
44+
45+
#include "absl/base/attributes.h"
46+
#include "absl/base/config.h"
47+
+#include "absl/base/internal/raw_logging.h"
48+
#include "absl/base/dynamic_annotations.h"
49+
#include "absl/container/internal/container_memory.h"
50+
#include "absl/hash/hash.h"
51+
@@ -375,6 +376,10 @@ void HashSetResizeHelper::GrowSizeIntoSingleGroupTransferable(
52+
PoisonSingleGroupEmptySlots(c, slot_size);
53+
}
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 3518bc3..b6124ed 100644
64+
--- a/absl/container/internal/raw_hash_set.h
65+
+++ b/absl/container/internal/raw_hash_set.h
66+
@@ -244,6 +244,15 @@ namespace container_internal {
67+
#define ABSL_SWISSTABLE_ENABLE_GENERATIONS
68+
#endif
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+
// We use uint8_t so we don't need to worry about padding.
80+
using GenerationType = uint8_t;
81+
82+
@@ -1017,6 +1026,9 @@ inline size_t SlotOffset(size_t capacity, size_t slot_align, bool has_infoz) {
83+
// array.
84+
inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align,
85+
bool has_infoz) {
86+
+ ABSL_SWISSTABLE_ASSERT(
87+
+ slot_size <=
88+
+ ((std::numeric_limits<size_t>::max)() - SlotOffset(capacity, slot_align, has_infoz)) / capacity);
89+
return SlotOffset(capacity, slot_align, has_infoz) + capacity * slot_size;
90+
}
91+
92+
@@ -1184,6 +1196,15 @@ inline size_t NormalizeCapacity(size_t n) {
93+
return n ? ~size_t{} >> countl_zero(n) : 1;
94+
}
95+
96+
+template <size_t kSlotSize>
97+
+size_t MaxValidCapacity() {
98+
+ return NormalizeCapacity((std::numeric_limits<size_t>::max)() / 4 /
99+
+ kSlotSize);
100+
+}
101+
+
102+
+// Use a non-inlined function to avoid code bloat.
103+
+[[noreturn]] void HashTableSizeOverflow();
104+
+
105+
// General notes on capacity/growth methods below:
106+
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
107+
// average of two empty slots per group.
108+
@@ -2093,6 +2114,10 @@ class raw_hash_set {
109+
const allocator_type& alloc = allocator_type())
110+
: settings_(CommonFields{}, hash, eq, alloc) {
111+
if (bucket_count) {
112+
+ if (ABSL_PREDICT_FALSE(bucket_count >
113+
+ MaxValidCapacity<sizeof(slot_type)>())) {
114+
+ HashTableSizeOverflow();
115+
+ }
116+
resize(NormalizeCapacity(bucket_count));
117+
}
118+
}
119+
@@ -2286,7 +2311,9 @@ class raw_hash_set {
120+
bool empty() const { return !size(); }
121+
size_t size() const { return common().size(); }
122+
size_t capacity() const { return common().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+
@@ -2624,6 +2651,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+
@@ -2634,6 +2664,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+
@@ -3321,5 +3354,6 @@ ABSL_NAMESPACE_END
151+
} // namespace absl
152+
153+
#undef ABSL_SWISSTABLE_ENABLE_GENERATIONS
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 f9797f5..1f579bf 100644
159+
--- a/absl/container/internal/raw_hash_set_test.cc
160+
+++ b/absl/container/internal/raw_hash_set_test.cc
161+
@@ -2678,6 +2678,14 @@ TEST(Table, CountedHash) {
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
@@ -5,12 +5,13 @@
55
Summary: C++ Common Libraries
66
Name: abseil-cpp
77
Version: 20240116.0
8-
Release: 2%{?dist}
8+
Release: 3%{?dist}
99
License: ASL 2.0
1010
Vendor: Microsoft Corporation
1111
Distribution: Azure Linux
1212
URL: https://abseil.io
1313
Source0: https://github.com/abseil/abseil-cpp/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz
14+
Patch0: CVE-2025-0838.patch
1415

1516
BuildRequires: cmake >= 3.20.0
1617
BuildRequires: gcc
@@ -94,6 +95,9 @@ Development headers for %{name}
9495
%{_libdir}/pkgconfig/*.pc
9596

9697
%changelog
98+
* Tue Feb 10 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 20240116.0-3
99+
- Patch for CVE-2025-0838
100+
97101
* Thu Jul 25 2024 Devin Anderson <danderson@microsoft.com> - 20240116.0-2
98102
- Change the build type back to 'RelWithDebInfo' so that 'abseil' compiles with
99103
'NDEBUG' defined so that packages that link to 'abseil' with 'NDEBUG' defined

0 commit comments

Comments
 (0)