xref: /aosp_15_r20/external/cronet/base/process/memory_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #define _CRT_SECURE_NO_WARNINGS
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/process/memory.h"
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include <limits>
12*6777b538SAndroid Build Coastguard Worker #include <tuple>
13*6777b538SAndroid Build Coastguard Worker #include <vector>
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker #include "base/allocator/allocator_check.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/debug/alias.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/aligned_memory.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/page_size.h"
20*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
21*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/page_allocator.h"
22*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/partition_alloc_buildflags.h"
23*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
26*6777b538SAndroid Build Coastguard Worker #include <windows.h>
27*6777b538SAndroid Build Coastguard Worker #endif
28*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX)
29*6777b538SAndroid Build Coastguard Worker #include <errno.h>
30*6777b538SAndroid Build Coastguard Worker #endif
31*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
32*6777b538SAndroid Build Coastguard Worker #include <malloc/malloc.h>
33*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/process/memory_unittest_mac.h"
35*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/shim/allocator_interception_apple.h"
36*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/shim/allocator_shim.h"
37*6777b538SAndroid Build Coastguard Worker #endif
38*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
39*6777b538SAndroid Build Coastguard Worker #include <malloc.h>
40*6777b538SAndroid Build Coastguard Worker #include "base/test/malloc_wrapper.h"
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
43*6777b538SAndroid Build Coastguard Worker #include "base/android/build_info.h"
44*6777b538SAndroid Build Coastguard Worker #endif
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
49*6777b538SAndroid Build Coastguard Worker // ssize_t needed for OutOfMemoryTest.
50*6777b538SAndroid Build Coastguard Worker #if defined(_WIN64)
51*6777b538SAndroid Build Coastguard Worker typedef __int64 ssize_t;
52*6777b538SAndroid Build Coastguard Worker #else
53*6777b538SAndroid Build Coastguard Worker typedef long ssize_t;
54*6777b538SAndroid Build Coastguard Worker #endif
55*6777b538SAndroid Build Coastguard Worker #endif
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker // HeapQueryInformation function pointer.
58*6777b538SAndroid Build Coastguard Worker typedef BOOL (WINAPI* HeapQueryFn)  \
59*6777b538SAndroid Build Coastguard Worker     (HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker // For the following Mac tests:
66*6777b538SAndroid Build Coastguard Worker // Note that base::EnableTerminationOnHeapCorruption() is called as part of
67*6777b538SAndroid Build Coastguard Worker // test suite setup and does not need to be done again, else mach_override
68*6777b538SAndroid Build Coastguard Worker // will fail.
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker // Wrap free() in a function to thwart Clang's -Wfree-nonheap-object warning.
callFree(void * ptr)71*6777b538SAndroid Build Coastguard Worker static void callFree(void *ptr) {
72*6777b538SAndroid Build Coastguard Worker   free(ptr);
73*6777b538SAndroid Build Coastguard Worker }
74*6777b538SAndroid Build Coastguard Worker 
TEST(ProcessMemoryTest,MacTerminateOnHeapCorruption)75*6777b538SAndroid Build Coastguard Worker TEST(ProcessMemoryTest, MacTerminateOnHeapCorruption) {
76*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
77*6777b538SAndroid Build Coastguard Worker   allocator_shim::InitializeAllocatorShim();
78*6777b538SAndroid Build Coastguard Worker #endif
79*6777b538SAndroid Build Coastguard Worker   // Assert that freeing an unallocated pointer will crash the process.
80*6777b538SAndroid Build Coastguard Worker   char buf[9];
81*6777b538SAndroid Build Coastguard Worker   asm("" : "=m"(buf));  // Prevent clang from being too smart.
82*6777b538SAndroid Build Coastguard Worker #if ARCH_CPU_64_BITS
83*6777b538SAndroid Build Coastguard Worker   // On 64 bit Macs, the malloc system automatically abort()s on heap corruption
84*6777b538SAndroid Build Coastguard Worker   // but does not output anything.
85*6777b538SAndroid Build Coastguard Worker   ASSERT_DEATH(callFree(buf), "");
86*6777b538SAndroid Build Coastguard Worker #elif defined(ADDRESS_SANITIZER)
87*6777b538SAndroid Build Coastguard Worker   // AddressSanitizer replaces malloc() and prints a different error message on
88*6777b538SAndroid Build Coastguard Worker   // heap corruption.
89*6777b538SAndroid Build Coastguard Worker   ASSERT_DEATH(callFree(buf), "attempting free on address which "
90*6777b538SAndroid Build Coastguard Worker       "was not malloc\\(\\)-ed");
91*6777b538SAndroid Build Coastguard Worker #else
92*6777b538SAndroid Build Coastguard Worker   ADD_FAILURE() << "This test is not supported in this build configuration.";
93*6777b538SAndroid Build Coastguard Worker #endif
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
96*6777b538SAndroid Build Coastguard Worker   allocator_shim::UninterceptMallocZonesForTesting();
97*6777b538SAndroid Build Coastguard Worker #endif
98*6777b538SAndroid Build Coastguard Worker }
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_MAC)
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
TEST(MemoryTest,AllocatorShimWorking)103*6777b538SAndroid Build Coastguard Worker TEST(MemoryTest, AllocatorShimWorking) {
104*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
105*6777b538SAndroid Build Coastguard Worker   allocator_shim::InitializeAllocatorShim();
106*6777b538SAndroid Build Coastguard Worker   allocator_shim::InterceptAllocationsMac();
107*6777b538SAndroid Build Coastguard Worker #endif
108*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::allocator::IsAllocatorInitialized());
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
111*6777b538SAndroid Build Coastguard Worker   allocator_shim::UninterceptMallocZonesForTesting();
112*6777b538SAndroid Build Coastguard Worker #endif
113*6777b538SAndroid Build Coastguard Worker }
114*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker // OpenBSD does not support these tests. Don't test these on ASan/TSan/MSan
117*6777b538SAndroid Build Coastguard Worker // configurations: only test the real allocator.
118*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_OPENBSD) && BUILDFLAG(USE_ALLOCATOR_SHIM) && \
119*6777b538SAndroid Build Coastguard Worker     !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker namespace {
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker // Windows raises an exception in order to make the exit code unique to OOM.
126*6777b538SAndroid Build Coastguard Worker #define ASSERT_OOM_DEATH(statement) \
127*6777b538SAndroid Build Coastguard Worker   ASSERT_EXIT(statement,            \
128*6777b538SAndroid Build Coastguard Worker               testing::ExitedWithCode(base::win::kOomExceptionCode), "")
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker #else
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker #define ASSERT_OOM_DEATH(statement) ASSERT_DEATH(statement, "")
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker }  // namespace
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker class OutOfMemoryTest : public testing::Test {
139*6777b538SAndroid Build Coastguard Worker  public:
OutOfMemoryTest()140*6777b538SAndroid Build Coastguard Worker   OutOfMemoryTest()
141*6777b538SAndroid Build Coastguard Worker       :  // Make test size as large as possible minus a few pages so that
142*6777b538SAndroid Build Coastguard Worker          // alignment or other rounding doesn't make it wrap.
143*6777b538SAndroid Build Coastguard Worker         test_size_(std::numeric_limits<std::size_t>::max() -
144*6777b538SAndroid Build Coastguard Worker                    3 * base::GetPageSize()),
145*6777b538SAndroid Build Coastguard Worker         // A test size that is > 2Gb and will cause the allocators to reject
146*6777b538SAndroid Build Coastguard Worker         // the allocation due to security restrictions. See crbug.com/169327.
147*6777b538SAndroid Build Coastguard Worker         insecure_test_size_(std::numeric_limits<int>::max()),
148*6777b538SAndroid Build Coastguard Worker         signed_test_size_(std::numeric_limits<ssize_t>::max()) {}
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker  protected:
151*6777b538SAndroid Build Coastguard Worker   size_t test_size_;
152*6777b538SAndroid Build Coastguard Worker   size_t insecure_test_size_;
153*6777b538SAndroid Build Coastguard Worker   ssize_t signed_test_size_;
154*6777b538SAndroid Build Coastguard Worker };
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker class OutOfMemoryDeathTest : public OutOfMemoryTest {
157*6777b538SAndroid Build Coastguard Worker  public:
SetUpInDeathAssert()158*6777b538SAndroid Build Coastguard Worker   void SetUpInDeathAssert() {
159*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_ALLOCATOR_SHIM)
160*6777b538SAndroid Build Coastguard Worker     allocator_shim::InitializeAllocatorShim();
161*6777b538SAndroid Build Coastguard Worker #endif
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker     // Must call EnableTerminationOnOutOfMemory() because that is called from
164*6777b538SAndroid Build Coastguard Worker     // chrome's main function and therefore hasn't been called yet.
165*6777b538SAndroid Build Coastguard Worker     // Since this call may result in another thread being created and death
166*6777b538SAndroid Build Coastguard Worker     // tests shouldn't be started in a multithread environment, this call
167*6777b538SAndroid Build Coastguard Worker     // should be done inside of the ASSERT_DEATH.
168*6777b538SAndroid Build Coastguard Worker     base::EnableTerminationOnOutOfMemory();
169*6777b538SAndroid Build Coastguard Worker   }
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
TearDown()172*6777b538SAndroid Build Coastguard Worker   void TearDown() override {
173*6777b538SAndroid Build Coastguard Worker     allocator_shim::UninterceptMallocZonesForTesting();
174*6777b538SAndroid Build Coastguard Worker   }
175*6777b538SAndroid Build Coastguard Worker #endif
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker   // These tests don't work properly on old x86 Android; crbug.com/1181112
ShouldSkipTest()178*6777b538SAndroid Build Coastguard Worker   bool ShouldSkipTest() {
179*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_X86)
180*6777b538SAndroid Build Coastguard Worker     return base::android::BuildInfo::GetInstance()->sdk_int() <
181*6777b538SAndroid Build Coastguard Worker            base::android::SDK_VERSION_NOUGAT;
182*6777b538SAndroid Build Coastguard Worker #else
183*6777b538SAndroid Build Coastguard Worker     return false;
184*6777b538SAndroid Build Coastguard Worker #endif
185*6777b538SAndroid Build Coastguard Worker   }
186*6777b538SAndroid Build Coastguard Worker };
187*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,New)188*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, New) {
189*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
190*6777b538SAndroid Build Coastguard Worker     return;
191*6777b538SAndroid Build Coastguard Worker   }
192*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
193*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
194*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = operator new(test_size_);
195*6777b538SAndroid Build Coastguard Worker   });
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,NewArray)198*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, NewArray) {
199*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
200*6777b538SAndroid Build Coastguard Worker     return;
201*6777b538SAndroid Build Coastguard Worker   }
202*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
203*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
204*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = new char[test_size_];
205*6777b538SAndroid Build Coastguard Worker   });
206*6777b538SAndroid Build Coastguard Worker }
207*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,Malloc)208*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Malloc) {
209*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
210*6777b538SAndroid Build Coastguard Worker     return;
211*6777b538SAndroid Build Coastguard Worker   }
212*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
213*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
214*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = malloc(test_size_);
215*6777b538SAndroid Build Coastguard Worker   });
216*6777b538SAndroid Build Coastguard Worker }
217*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,Realloc)218*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Realloc) {
219*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
220*6777b538SAndroid Build Coastguard Worker     return;
221*6777b538SAndroid Build Coastguard Worker   }
222*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
223*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
224*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = realloc(nullptr, test_size_);
225*6777b538SAndroid Build Coastguard Worker   });
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,Calloc)228*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Calloc) {
229*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
230*6777b538SAndroid Build Coastguard Worker     return;
231*6777b538SAndroid Build Coastguard Worker   }
232*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
233*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
234*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = calloc(1024, test_size_ / 1024L);
235*6777b538SAndroid Build Coastguard Worker   });
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,AlignedAlloc)238*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, AlignedAlloc) {
239*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
240*6777b538SAndroid Build Coastguard Worker     return;
241*6777b538SAndroid Build Coastguard Worker   }
242*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
243*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
244*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = base::AlignedAlloc(test_size_, 8);
245*6777b538SAndroid Build Coastguard Worker   });
246*6777b538SAndroid Build Coastguard Worker }
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker // POSIX does not define an aligned realloc function.
249*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
TEST_F(OutOfMemoryDeathTest,AlignedRealloc)250*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, AlignedRealloc) {
251*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
252*6777b538SAndroid Build Coastguard Worker     return;
253*6777b538SAndroid Build Coastguard Worker   }
254*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
255*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
256*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
257*6777b538SAndroid Build Coastguard Worker         _aligned_realloc(nullptr, test_size_, 8);
258*6777b538SAndroid Build Coastguard Worker   });
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker 
261*6777b538SAndroid Build Coastguard Worker namespace {
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker constexpr uint32_t kUnhandledExceptionExitCode = 0xBADA55;
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker // This unhandled exception filter exits the process with an exit code distinct
266*6777b538SAndroid Build Coastguard Worker // from the exception code. This is to verify that the out of memory new handler
267*6777b538SAndroid Build Coastguard Worker // causes an unhandled exception.
ExitingUnhandledExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)268*6777b538SAndroid Build Coastguard Worker LONG WINAPI ExitingUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo) {
269*6777b538SAndroid Build Coastguard Worker   _exit(kUnhandledExceptionExitCode);
270*6777b538SAndroid Build Coastguard Worker }
271*6777b538SAndroid Build Coastguard Worker 
272*6777b538SAndroid Build Coastguard Worker }  // namespace
273*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,NewHandlerGeneratesUnhandledException)274*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, NewHandlerGeneratesUnhandledException) {
275*6777b538SAndroid Build Coastguard Worker   ASSERT_EXIT(
276*6777b538SAndroid Build Coastguard Worker       {
277*6777b538SAndroid Build Coastguard Worker         SetUpInDeathAssert();
278*6777b538SAndroid Build Coastguard Worker         SetUnhandledExceptionFilter(&ExitingUnhandledExceptionFilter);
279*6777b538SAndroid Build Coastguard Worker         [[maybe_unused]] void* volatile ptr = new char[test_size_];
280*6777b538SAndroid Build Coastguard Worker       },
281*6777b538SAndroid Build Coastguard Worker       testing::ExitedWithCode(kUnhandledExceptionExitCode), "");
282*6777b538SAndroid Build Coastguard Worker }
283*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
284*6777b538SAndroid Build Coastguard Worker 
285*6777b538SAndroid Build Coastguard Worker // OS X has no 2Gb allocation limit.
286*6777b538SAndroid Build Coastguard Worker // See https://crbug.com/169327.
287*6777b538SAndroid Build Coastguard Worker // PartitionAlloc is not active in component builds, so cannot enforce
288*6777b538SAndroid Build Coastguard Worker // this limit. (//BUILD.gn asserts that we cannot have an official component
289*6777b538SAndroid Build Coastguard Worker // build.)
290*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_MAC) && !defined(COMPONENT_BUILD)
TEST_F(OutOfMemoryDeathTest,SecurityNew)291*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityNew) {
292*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
293*6777b538SAndroid Build Coastguard Worker     return;
294*6777b538SAndroid Build Coastguard Worker   }
295*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
296*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
297*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = operator new(insecure_test_size_);
298*6777b538SAndroid Build Coastguard Worker   });
299*6777b538SAndroid Build Coastguard Worker }
300*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityNewArray)301*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityNewArray) {
302*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
303*6777b538SAndroid Build Coastguard Worker     return;
304*6777b538SAndroid Build Coastguard Worker   }
305*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
306*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
307*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = new char[insecure_test_size_];
308*6777b538SAndroid Build Coastguard Worker   });
309*6777b538SAndroid Build Coastguard Worker }
310*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityMalloc)311*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityMalloc) {
312*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
313*6777b538SAndroid Build Coastguard Worker     return;
314*6777b538SAndroid Build Coastguard Worker   }
315*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
316*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
317*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = malloc(insecure_test_size_);
318*6777b538SAndroid Build Coastguard Worker   });
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityRealloc)321*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityRealloc) {
322*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
323*6777b538SAndroid Build Coastguard Worker     return;
324*6777b538SAndroid Build Coastguard Worker   }
325*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
326*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
327*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = realloc(nullptr, insecure_test_size_);
328*6777b538SAndroid Build Coastguard Worker   });
329*6777b538SAndroid Build Coastguard Worker }
330*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityCalloc)331*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityCalloc) {
332*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
333*6777b538SAndroid Build Coastguard Worker     return;
334*6777b538SAndroid Build Coastguard Worker   }
335*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
336*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
337*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
338*6777b538SAndroid Build Coastguard Worker         calloc(1024, insecure_test_size_ / 1024L);
339*6777b538SAndroid Build Coastguard Worker   });
340*6777b538SAndroid Build Coastguard Worker }
341*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityAlignedAlloc)342*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityAlignedAlloc) {
343*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
344*6777b538SAndroid Build Coastguard Worker     return;
345*6777b538SAndroid Build Coastguard Worker   }
346*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
347*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
348*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
349*6777b538SAndroid Build Coastguard Worker         base::AlignedAlloc(insecure_test_size_, 8);
350*6777b538SAndroid Build Coastguard Worker   });
351*6777b538SAndroid Build Coastguard Worker }
352*6777b538SAndroid Build Coastguard Worker 
353*6777b538SAndroid Build Coastguard Worker // POSIX does not define an aligned realloc function.
354*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
TEST_F(OutOfMemoryDeathTest,SecurityAlignedRealloc)355*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityAlignedRealloc) {
356*6777b538SAndroid Build Coastguard Worker   if (ShouldSkipTest()) {
357*6777b538SAndroid Build Coastguard Worker     return;
358*6777b538SAndroid Build Coastguard Worker   }
359*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
360*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
361*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
362*6777b538SAndroid Build Coastguard Worker         _aligned_realloc(nullptr, insecure_test_size_, 8);
363*6777b538SAndroid Build Coastguard Worker   });
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
366*6777b538SAndroid Build Coastguard Worker #endif  // !BUILDFLAG(IS_MAC)
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
369*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,Valloc)370*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Valloc) {
371*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
372*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
373*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = valloc(test_size_);
374*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(ptr);
375*6777b538SAndroid Build Coastguard Worker   });
376*6777b538SAndroid Build Coastguard Worker }
377*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityValloc)378*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityValloc) {
379*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
380*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
381*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = valloc(insecure_test_size_);
382*6777b538SAndroid Build Coastguard Worker   });
383*6777b538SAndroid Build Coastguard Worker }
384*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,Pvalloc)385*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Pvalloc) {
386*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
387*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
388*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = pvalloc(test_size_);
389*6777b538SAndroid Build Coastguard Worker   });
390*6777b538SAndroid Build Coastguard Worker }
391*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,SecurityPvalloc)392*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityPvalloc) {
393*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
394*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
395*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = pvalloc(insecure_test_size_);
396*6777b538SAndroid Build Coastguard Worker   });
397*6777b538SAndroid Build Coastguard Worker }
398*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,Memalign)399*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Memalign) {
400*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
401*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
402*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = memalign(4, test_size_);
403*6777b538SAndroid Build Coastguard Worker   });
404*6777b538SAndroid Build Coastguard Worker }
405*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,ViaSharedLibraries)406*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, ViaSharedLibraries) {
407*6777b538SAndroid Build Coastguard Worker   // This tests that the run-time symbol resolution is overriding malloc for
408*6777b538SAndroid Build Coastguard Worker   // shared libraries as well as for our code.
409*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
410*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
411*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = MallocWrapper(test_size_);
412*6777b538SAndroid Build Coastguard Worker   });
413*6777b538SAndroid Build Coastguard Worker }
414*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
415*6777b538SAndroid Build Coastguard Worker 
416*6777b538SAndroid Build Coastguard Worker // Android doesn't implement posix_memalign().
417*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
TEST_F(OutOfMemoryDeathTest,Posix_memalign)418*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Posix_memalign) {
419*6777b538SAndroid Build Coastguard Worker   // Grab the return value of posix_memalign to silence a compiler warning
420*6777b538SAndroid Build Coastguard Worker   // about unused return values. We don't actually care about the return
421*6777b538SAndroid Build Coastguard Worker   // value, since we're asserting death.
422*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
423*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
424*6777b538SAndroid Build Coastguard Worker     void* ptr;
425*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ENOMEM, posix_memalign(&ptr, 8, test_size_));
426*6777b538SAndroid Build Coastguard Worker   });
427*6777b538SAndroid Build Coastguard Worker }
428*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
429*6777b538SAndroid Build Coastguard Worker 
430*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
431*6777b538SAndroid Build Coastguard Worker 
432*6777b538SAndroid Build Coastguard Worker // Purgeable zone tests
433*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,MallocPurgeable)434*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, MallocPurgeable) {
435*6777b538SAndroid Build Coastguard Worker   malloc_zone_t* zone = malloc_default_purgeable_zone();
436*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
437*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
438*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = malloc_zone_malloc(zone, test_size_);
439*6777b538SAndroid Build Coastguard Worker   });
440*6777b538SAndroid Build Coastguard Worker }
441*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,ReallocPurgeable)442*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, ReallocPurgeable) {
443*6777b538SAndroid Build Coastguard Worker   malloc_zone_t* zone = malloc_default_purgeable_zone();
444*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
445*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
446*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
447*6777b538SAndroid Build Coastguard Worker         malloc_zone_realloc(zone, nullptr, test_size_);
448*6777b538SAndroid Build Coastguard Worker   });
449*6777b538SAndroid Build Coastguard Worker }
450*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,CallocPurgeable)451*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, CallocPurgeable) {
452*6777b538SAndroid Build Coastguard Worker   malloc_zone_t* zone = malloc_default_purgeable_zone();
453*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
454*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
455*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
456*6777b538SAndroid Build Coastguard Worker         malloc_zone_calloc(zone, 1024, test_size_ / 1024L);
457*6777b538SAndroid Build Coastguard Worker   });
458*6777b538SAndroid Build Coastguard Worker }
459*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,VallocPurgeable)460*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, VallocPurgeable) {
461*6777b538SAndroid Build Coastguard Worker   malloc_zone_t* zone = malloc_default_purgeable_zone();
462*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
463*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
464*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr = malloc_zone_valloc(zone, test_size_);
465*6777b538SAndroid Build Coastguard Worker   });
466*6777b538SAndroid Build Coastguard Worker }
467*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,PosixMemalignPurgeable)468*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, PosixMemalignPurgeable) {
469*6777b538SAndroid Build Coastguard Worker   malloc_zone_t* zone = malloc_default_purgeable_zone();
470*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
471*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
472*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* volatile ptr =
473*6777b538SAndroid Build Coastguard Worker         malloc_zone_memalign(zone, 8, test_size_);
474*6777b538SAndroid Build Coastguard Worker   });
475*6777b538SAndroid Build Coastguard Worker }
476*6777b538SAndroid Build Coastguard Worker 
477*6777b538SAndroid Build Coastguard Worker // Since these allocation functions take a signed size, it's possible that
478*6777b538SAndroid Build Coastguard Worker // calling them just once won't be enough to exhaust memory. In the 32-bit
479*6777b538SAndroid Build Coastguard Worker // environment, it's likely that these allocation attempts will fail because
480*6777b538SAndroid Build Coastguard Worker // not enough contiguous address space is available. In the 64-bit environment,
481*6777b538SAndroid Build Coastguard Worker // it's likely that they'll fail because they would require a preposterous
482*6777b538SAndroid Build Coastguard Worker // amount of (virtual) memory.
483*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,CFAllocatorMalloc)484*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, CFAllocatorMalloc) {
485*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
486*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
487*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* ptr;
488*6777b538SAndroid Build Coastguard Worker     while ((ptr = base::AllocateViaCFAllocatorMalloc(signed_test_size_))) {
489*6777b538SAndroid Build Coastguard Worker     }
490*6777b538SAndroid Build Coastguard Worker   });
491*6777b538SAndroid Build Coastguard Worker }
492*6777b538SAndroid Build Coastguard Worker 
493*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
494*6777b538SAndroid Build Coastguard Worker // PartitionAlloc-Everywhere does not intercept other malloc zones than the
495*6777b538SAndroid Build Coastguard Worker // default (the top) malloc zone.  Plus,
496*6777b538SAndroid Build Coastguard Worker // CFAllocatorAllocate(kCFAllocatorSystemDefault, size, 0) does not call the
497*6777b538SAndroid Build Coastguard Worker // default (the top) malloc zone on macOS 10.xx (does call it on macOS 11 and
498*6777b538SAndroid Build Coastguard Worker // later though).
499*6777b538SAndroid Build Coastguard Worker #define MAYBE_CFAllocatorSystemDefault DISABLED_CFAllocatorSystemDefault
500*6777b538SAndroid Build Coastguard Worker #else
501*6777b538SAndroid Build Coastguard Worker #define MAYBE_CFAllocatorSystemDefault CFAllocatorSystemDefault
502*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(OutOfMemoryDeathTest,MAYBE_CFAllocatorSystemDefault)503*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, MAYBE_CFAllocatorSystemDefault) {
504*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
505*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
506*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* ptr;
507*6777b538SAndroid Build Coastguard Worker     while (
508*6777b538SAndroid Build Coastguard Worker         (ptr = base::AllocateViaCFAllocatorSystemDefault(signed_test_size_))) {
509*6777b538SAndroid Build Coastguard Worker     }
510*6777b538SAndroid Build Coastguard Worker   });
511*6777b538SAndroid Build Coastguard Worker }
512*6777b538SAndroid Build Coastguard Worker 
513*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
514*6777b538SAndroid Build Coastguard Worker // PartitionAlloc-Everywhere does not intercept other malloc zones than the
515*6777b538SAndroid Build Coastguard Worker // default (the top) malloc zone.  Plus,
516*6777b538SAndroid Build Coastguard Worker // CFAllocatorAllocate(kCFAllocatorMallocZone, size, 0) does not call the
517*6777b538SAndroid Build Coastguard Worker // default (the top) malloc zone on macOS 10.xx (does call it on macOS 11 and
518*6777b538SAndroid Build Coastguard Worker // later though).
519*6777b538SAndroid Build Coastguard Worker #define MAYBE_CFAllocatorMallocZone DISABLED_CFAllocatorMallocZone
520*6777b538SAndroid Build Coastguard Worker #else
521*6777b538SAndroid Build Coastguard Worker #define MAYBE_CFAllocatorMallocZone CFAllocatorMallocZone
522*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(OutOfMemoryDeathTest,MAYBE_CFAllocatorMallocZone)523*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, MAYBE_CFAllocatorMallocZone) {
524*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
525*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
526*6777b538SAndroid Build Coastguard Worker     [[maybe_unused]] void* ptr;
527*6777b538SAndroid Build Coastguard Worker     while ((ptr = base::AllocateViaCFAllocatorMallocZone(signed_test_size_))) {
528*6777b538SAndroid Build Coastguard Worker     }
529*6777b538SAndroid Build Coastguard Worker   });
530*6777b538SAndroid Build Coastguard Worker }
531*6777b538SAndroid Build Coastguard Worker 
532*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_MAC)
533*6777b538SAndroid Build Coastguard Worker 
534*6777b538SAndroid Build Coastguard Worker class OutOfMemoryHandledTest : public OutOfMemoryTest {
535*6777b538SAndroid Build Coastguard Worker  public:
536*6777b538SAndroid Build Coastguard Worker   static const size_t kSafeMallocSize = 512;
537*6777b538SAndroid Build Coastguard Worker   static const size_t kSafeCallocSize = 128;
538*6777b538SAndroid Build Coastguard Worker   static const size_t kSafeCallocItems = 4;
539*6777b538SAndroid Build Coastguard Worker 
SetUp()540*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
541*6777b538SAndroid Build Coastguard Worker     OutOfMemoryTest::SetUp();
542*6777b538SAndroid Build Coastguard Worker 
543*6777b538SAndroid Build Coastguard Worker     // We enable termination on OOM - just as Chrome does at early
544*6777b538SAndroid Build Coastguard Worker     // initialization - and test that UncheckedMalloc and  UncheckedCalloc
545*6777b538SAndroid Build Coastguard Worker     // properly by-pass this in order to allow the caller to handle OOM.
546*6777b538SAndroid Build Coastguard Worker     base::EnableTerminationOnOutOfMemory();
547*6777b538SAndroid Build Coastguard Worker   }
548*6777b538SAndroid Build Coastguard Worker 
TearDown()549*6777b538SAndroid Build Coastguard Worker   void TearDown() override {
550*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC)
551*6777b538SAndroid Build Coastguard Worker     allocator_shim::UninterceptMallocZonesForTesting();
552*6777b538SAndroid Build Coastguard Worker #endif
553*6777b538SAndroid Build Coastguard Worker   }
554*6777b538SAndroid Build Coastguard Worker };
555*6777b538SAndroid Build Coastguard Worker 
556*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
557*6777b538SAndroid Build Coastguard Worker 
558*6777b538SAndroid Build Coastguard Worker namespace {
559*6777b538SAndroid Build Coastguard Worker 
HandleOutOfMemoryException(EXCEPTION_POINTERS * exception_ptrs,size_t expected_size)560*6777b538SAndroid Build Coastguard Worker DWORD HandleOutOfMemoryException(EXCEPTION_POINTERS* exception_ptrs,
561*6777b538SAndroid Build Coastguard Worker                                  size_t expected_size) {
562*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::win::kOomExceptionCode,
563*6777b538SAndroid Build Coastguard Worker             exception_ptrs->ExceptionRecord->ExceptionCode);
564*6777b538SAndroid Build Coastguard Worker   EXPECT_LE(1U, exception_ptrs->ExceptionRecord->NumberParameters);
565*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_size,
566*6777b538SAndroid Build Coastguard Worker             exception_ptrs->ExceptionRecord->ExceptionInformation[0]);
567*6777b538SAndroid Build Coastguard Worker   return EXCEPTION_EXECUTE_HANDLER;
568*6777b538SAndroid Build Coastguard Worker }
569*6777b538SAndroid Build Coastguard Worker 
570*6777b538SAndroid Build Coastguard Worker }  // namespace
571*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryTest,TerminateBecauseOutOfMemoryReportsAllocSize)572*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryTest, TerminateBecauseOutOfMemoryReportsAllocSize) {
573*6777b538SAndroid Build Coastguard Worker // On Windows, TerminateBecauseOutOfMemory reports the attempted allocation
574*6777b538SAndroid Build Coastguard Worker // size in the exception raised.
575*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_64_BITS)
576*6777b538SAndroid Build Coastguard Worker   // Test with a size larger than 32 bits on 64 bit machines.
577*6777b538SAndroid Build Coastguard Worker   const size_t kAttemptedAllocationSize = 0xBADA55F00DULL;
578*6777b538SAndroid Build Coastguard Worker #else
579*6777b538SAndroid Build Coastguard Worker   const size_t kAttemptedAllocationSize = 0xBADA55;
580*6777b538SAndroid Build Coastguard Worker #endif
581*6777b538SAndroid Build Coastguard Worker 
582*6777b538SAndroid Build Coastguard Worker   __try {
583*6777b538SAndroid Build Coastguard Worker     base::TerminateBecauseOutOfMemory(kAttemptedAllocationSize);
584*6777b538SAndroid Build Coastguard Worker   } __except (HandleOutOfMemoryException(GetExceptionInformation(),
585*6777b538SAndroid Build Coastguard Worker                                          kAttemptedAllocationSize)) {
586*6777b538SAndroid Build Coastguard Worker   }
587*6777b538SAndroid Build Coastguard Worker }
588*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_WIN)
589*6777b538SAndroid Build Coastguard Worker 
590*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_32_BITS) && \
591*6777b538SAndroid Build Coastguard Worker     (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
592*6777b538SAndroid Build Coastguard Worker 
TestAllocationsReleaseReservation(void * (* alloc_fn)(size_t),void (* free_fn)(void *))593*6777b538SAndroid Build Coastguard Worker void TestAllocationsReleaseReservation(void* (*alloc_fn)(size_t),
594*6777b538SAndroid Build Coastguard Worker                                        void (*free_fn)(void*)) {
595*6777b538SAndroid Build Coastguard Worker   partition_alloc::ReleaseReservation();
596*6777b538SAndroid Build Coastguard Worker   base::EnableTerminationOnOutOfMemory();
597*6777b538SAndroid Build Coastguard Worker 
598*6777b538SAndroid Build Coastguard Worker   constexpr size_t kMiB = 1 << 20;
599*6777b538SAndroid Build Coastguard Worker   constexpr size_t kReservationSize = 512 * kMiB;  // MiB.
600*6777b538SAndroid Build Coastguard Worker 
601*6777b538SAndroid Build Coastguard Worker   size_t reservation_size = kReservationSize;
602*6777b538SAndroid Build Coastguard Worker   while (!partition_alloc::ReserveAddressSpace(reservation_size)) {
603*6777b538SAndroid Build Coastguard Worker     reservation_size -= 16 * kMiB;
604*6777b538SAndroid Build Coastguard Worker   }
605*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(partition_alloc::HasReservationForTesting());
606*6777b538SAndroid Build Coastguard Worker   ASSERT_GT(reservation_size, 0u);
607*6777b538SAndroid Build Coastguard Worker 
608*6777b538SAndroid Build Coastguard Worker   // Allocate a large area at a time to bump into address space exhaustion
609*6777b538SAndroid Build Coastguard Worker   // before other limits. It is important not to do a larger allocation, to
610*6777b538SAndroid Build Coastguard Worker   // verify that we can allocate without removing the reservation. On the other
611*6777b538SAndroid Build Coastguard Worker   // hand, must be large enough to make the underlying implementation call
612*6777b538SAndroid Build Coastguard Worker   // mmap()/VirtualAlloc().
613*6777b538SAndroid Build Coastguard Worker   size_t allocation_size = reservation_size / 2;
614*6777b538SAndroid Build Coastguard Worker 
615*6777b538SAndroid Build Coastguard Worker   std::vector<void*> areas;
616*6777b538SAndroid Build Coastguard Worker   // Pre-reserve the vector to make sure that we don't hit the address space
617*6777b538SAndroid Build Coastguard Worker   // limit while resizing the array.
618*6777b538SAndroid Build Coastguard Worker   areas.reserve(((2 * 4096 * kMiB) / allocation_size) + 1);
619*6777b538SAndroid Build Coastguard Worker 
620*6777b538SAndroid Build Coastguard Worker   while (true) {
621*6777b538SAndroid Build Coastguard Worker     void* area = alloc_fn(allocation_size / 2);
622*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(area);
623*6777b538SAndroid Build Coastguard Worker     areas.push_back(area);
624*6777b538SAndroid Build Coastguard Worker 
625*6777b538SAndroid Build Coastguard Worker     // Working as intended, the allocation was successful, and the reservation
626*6777b538SAndroid Build Coastguard Worker     // was dropped instead of crashing.
627*6777b538SAndroid Build Coastguard Worker     //
628*6777b538SAndroid Build Coastguard Worker     // Meaning that the test is either successful, or crashes.
629*6777b538SAndroid Build Coastguard Worker     if (!partition_alloc::HasReservationForTesting())
630*6777b538SAndroid Build Coastguard Worker       break;
631*6777b538SAndroid Build Coastguard Worker   }
632*6777b538SAndroid Build Coastguard Worker 
633*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(areas.size(), 2u)
634*6777b538SAndroid Build Coastguard Worker       << "Should be able to allocate without releasing the reservation";
635*6777b538SAndroid Build Coastguard Worker 
636*6777b538SAndroid Build Coastguard Worker   for (void* ptr : areas)
637*6777b538SAndroid Build Coastguard Worker     free_fn(ptr);
638*6777b538SAndroid Build Coastguard Worker }
639*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryHandledTest,MallocReleasesReservation)640*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryHandledTest, MallocReleasesReservation) {
641*6777b538SAndroid Build Coastguard Worker   TestAllocationsReleaseReservation(malloc, free);
642*6777b538SAndroid Build Coastguard Worker }
643*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryHandledTest,NewReleasesReservation)644*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryHandledTest, NewReleasesReservation) {
645*6777b538SAndroid Build Coastguard Worker   TestAllocationsReleaseReservation(
646*6777b538SAndroid Build Coastguard Worker       [](size_t size) { return static_cast<void*>(new char[size]); },
647*6777b538SAndroid Build Coastguard Worker       [](void* ptr) { delete[] static_cast<char*>(ptr); });
648*6777b538SAndroid Build Coastguard Worker }
649*6777b538SAndroid Build Coastguard Worker #endif  // defined(ARCH_CPU_32_BITS) && (BUILDFLAG(IS_WIN) ||
650*6777b538SAndroid Build Coastguard Worker         // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
651*6777b538SAndroid Build Coastguard Worker 
652*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
653*6777b538SAndroid Build Coastguard Worker 
654*6777b538SAndroid Build Coastguard Worker // Android's allocator does not allow overcommits, so very large
655*6777b538SAndroid Build Coastguard Worker // UncheckedMallocs will yield OOM errors.
656*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1112840): Fails on some Android bots.
657*6777b538SAndroid Build Coastguard Worker #define MAYBE_UncheckedMallocDies DISABLED_UncheckedMallocDies
658*6777b538SAndroid Build Coastguard Worker #define MAYBE_UncheckedCallocDies DISABLED_UncheckedCallocDies
TEST_F(OutOfMemoryDeathTest,MAYBE_UncheckedMallocDies)659*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, MAYBE_UncheckedMallocDies) {
660*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
661*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
662*6777b538SAndroid Build Coastguard Worker     void* data;
663*6777b538SAndroid Build Coastguard Worker     std::ignore = base::UncheckedMalloc(test_size_, &data);
664*6777b538SAndroid Build Coastguard Worker     // Death expected here.
665*6777b538SAndroid Build Coastguard Worker   });
666*6777b538SAndroid Build Coastguard Worker }
667*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryDeathTest,MAYBE_UncheckedCallocDies)668*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, MAYBE_UncheckedCallocDies) {
669*6777b538SAndroid Build Coastguard Worker   ASSERT_OOM_DEATH({
670*6777b538SAndroid Build Coastguard Worker     SetUpInDeathAssert();
671*6777b538SAndroid Build Coastguard Worker     void* data;
672*6777b538SAndroid Build Coastguard Worker     std::ignore = base::UncheckedCalloc(1, test_size_, &data);
673*6777b538SAndroid Build Coastguard Worker     // Death expected here.
674*6777b538SAndroid Build Coastguard Worker   });
675*6777b538SAndroid Build Coastguard Worker }
676*6777b538SAndroid Build Coastguard Worker 
677*6777b538SAndroid Build Coastguard Worker #else
678*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryHandledTest,UncheckedMalloc)679*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryHandledTest, UncheckedMalloc) {
680*6777b538SAndroid Build Coastguard Worker   void* ptr;
681*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::UncheckedMalloc(kSafeMallocSize, &ptr));
682*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ptr != nullptr);
683*6777b538SAndroid Build Coastguard Worker   base::UncheckedFree(ptr);
684*6777b538SAndroid Build Coastguard Worker 
685*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::UncheckedMalloc(test_size_, &ptr));
686*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ptr == nullptr);
687*6777b538SAndroid Build Coastguard Worker }
688*6777b538SAndroid Build Coastguard Worker 
TEST_F(OutOfMemoryHandledTest,UncheckedCalloc)689*6777b538SAndroid Build Coastguard Worker TEST_F(OutOfMemoryHandledTest, UncheckedCalloc) {
690*6777b538SAndroid Build Coastguard Worker   void* ptr;
691*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::UncheckedCalloc(1, kSafeMallocSize, &ptr));
692*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ptr != nullptr);
693*6777b538SAndroid Build Coastguard Worker   const char* bytes = static_cast<const char*>(ptr);
694*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < kSafeMallocSize; ++i)
695*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, bytes[i]);
696*6777b538SAndroid Build Coastguard Worker   base::UncheckedFree(ptr);
697*6777b538SAndroid Build Coastguard Worker 
698*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::UncheckedCalloc(kSafeCallocItems, kSafeCallocSize, &ptr));
699*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ptr != nullptr);
700*6777b538SAndroid Build Coastguard Worker   bytes = static_cast<const char*>(ptr);
701*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i)
702*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, bytes[i]);
703*6777b538SAndroid Build Coastguard Worker   base::UncheckedFree(ptr);
704*6777b538SAndroid Build Coastguard Worker 
705*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &ptr));
706*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ptr == nullptr);
707*6777b538SAndroid Build Coastguard Worker }
708*6777b538SAndroid Build Coastguard Worker 
709*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_ANDROID)
710*6777b538SAndroid Build Coastguard Worker #endif  // !BUILDFLAG(IS_OPENBSD) && BUILDFLAG(USE_ALLOCATOR_SHIM) &&
711*6777b538SAndroid Build Coastguard Worker         // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
712*6777b538SAndroid Build Coastguard Worker 
713*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
714*6777b538SAndroid Build Coastguard Worker 
715*6777b538SAndroid Build Coastguard Worker // Not a proper test because it needs to be in a static initializer, see the
716*6777b538SAndroid Build Coastguard Worker // comment in UncheckedMalloc() in memory_mac.mm.
717*6777b538SAndroid Build Coastguard Worker //
718*6777b538SAndroid Build Coastguard Worker // The "test" passes if the binary doesn't crash.
__anon9b2557250602() 719*6777b538SAndroid Build Coastguard Worker size_t need_a_static_initializer = []() {
720*6777b538SAndroid Build Coastguard Worker   void* ptr;
721*6777b538SAndroid Build Coastguard Worker   constexpr size_t kRequestedSize = 1000u;
722*6777b538SAndroid Build Coastguard Worker   bool ok = base::UncheckedMalloc(kRequestedSize, &ptr);
723*6777b538SAndroid Build Coastguard Worker   CHECK(ok);
724*6777b538SAndroid Build Coastguard Worker   size_t actual_size = malloc_size(ptr);
725*6777b538SAndroid Build Coastguard Worker   // If no known zone owns the pointer, dispatching code in libmalloc returns 0.
726*6777b538SAndroid Build Coastguard Worker   CHECK_GE(actual_size, kRequestedSize);
727*6777b538SAndroid Build Coastguard Worker   // If no zone owns the pointer, libmalloc aborts here.
728*6777b538SAndroid Build Coastguard Worker   free(ptr);
729*6777b538SAndroid Build Coastguard Worker 
730*6777b538SAndroid Build Coastguard Worker   return actual_size;
731*6777b538SAndroid Build Coastguard Worker }();
732*6777b538SAndroid Build Coastguard Worker 
733*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
734