1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #define _CRT_SECURE_NO_WARNINGS
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include "base/process/memory.h"
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include <limits>
12*635a8641SAndroid Build Coastguard Worker
13*635a8641SAndroid Build Coastguard Worker #include "base/allocator/allocator_check.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/allocator/buildflags.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/debug/alias.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/memory/aligned_memory.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
19*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
20*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
23*635a8641SAndroid Build Coastguard Worker #include <windows.h>
24*635a8641SAndroid Build Coastguard Worker #endif
25*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
26*635a8641SAndroid Build Coastguard Worker #include <errno.h>
27*635a8641SAndroid Build Coastguard Worker #endif
28*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
29*635a8641SAndroid Build Coastguard Worker #include <malloc/malloc.h>
30*635a8641SAndroid Build Coastguard Worker #include "base/allocator/allocator_interception_mac.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/allocator/allocator_shim.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/process/memory_unittest_mac.h"
33*635a8641SAndroid Build Coastguard Worker #endif
34*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
35*635a8641SAndroid Build Coastguard Worker #include <malloc.h>
36*635a8641SAndroid Build Coastguard Worker #include "base/test/malloc_wrapper.h"
37*635a8641SAndroid Build Coastguard Worker #endif
38*635a8641SAndroid Build Coastguard Worker
39*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
42*635a8641SAndroid Build Coastguard Worker // ssize_t needed for OutOfMemoryTest.
43*635a8641SAndroid Build Coastguard Worker #if defined(_WIN64)
44*635a8641SAndroid Build Coastguard Worker typedef __int64 ssize_t;
45*635a8641SAndroid Build Coastguard Worker #else
46*635a8641SAndroid Build Coastguard Worker typedef long ssize_t;
47*635a8641SAndroid Build Coastguard Worker #endif
48*635a8641SAndroid Build Coastguard Worker #endif
49*635a8641SAndroid Build Coastguard Worker
50*635a8641SAndroid Build Coastguard Worker // HeapQueryInformation function pointer.
51*635a8641SAndroid Build Coastguard Worker typedef BOOL (WINAPI* HeapQueryFn) \
52*635a8641SAndroid Build Coastguard Worker (HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
53*635a8641SAndroid Build Coastguard Worker
54*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_WIN)
55*635a8641SAndroid Build Coastguard Worker
56*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
57*635a8641SAndroid Build Coastguard Worker
58*635a8641SAndroid Build Coastguard Worker // For the following Mac tests:
59*635a8641SAndroid Build Coastguard Worker // Note that base::EnableTerminationOnHeapCorruption() is called as part of
60*635a8641SAndroid Build Coastguard Worker // test suite setup and does not need to be done again, else mach_override
61*635a8641SAndroid Build Coastguard Worker // will fail.
62*635a8641SAndroid Build Coastguard Worker
TEST(ProcessMemoryTest,MacTerminateOnHeapCorruption)63*635a8641SAndroid Build Coastguard Worker TEST(ProcessMemoryTest, MacTerminateOnHeapCorruption) {
64*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
65*635a8641SAndroid Build Coastguard Worker base::allocator::InitializeAllocatorShim();
66*635a8641SAndroid Build Coastguard Worker #endif
67*635a8641SAndroid Build Coastguard Worker // Assert that freeing an unallocated pointer will crash the process.
68*635a8641SAndroid Build Coastguard Worker char buf[9];
69*635a8641SAndroid Build Coastguard Worker asm("" : "=r" (buf)); // Prevent clang from being too smart.
70*635a8641SAndroid Build Coastguard Worker #if ARCH_CPU_64_BITS
71*635a8641SAndroid Build Coastguard Worker // On 64 bit Macs, the malloc system automatically abort()s on heap corruption
72*635a8641SAndroid Build Coastguard Worker // but does not output anything.
73*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH(free(buf), "");
74*635a8641SAndroid Build Coastguard Worker #elif defined(ADDRESS_SANITIZER)
75*635a8641SAndroid Build Coastguard Worker // AddressSanitizer replaces malloc() and prints a different error message on
76*635a8641SAndroid Build Coastguard Worker // heap corruption.
77*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH(free(buf), "attempting free on address which "
78*635a8641SAndroid Build Coastguard Worker "was not malloc\\(\\)-ed");
79*635a8641SAndroid Build Coastguard Worker #else
80*635a8641SAndroid Build Coastguard Worker ADD_FAILURE() << "This test is not supported in this build configuration.";
81*635a8641SAndroid Build Coastguard Worker #endif
82*635a8641SAndroid Build Coastguard Worker
83*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
84*635a8641SAndroid Build Coastguard Worker base::allocator::UninterceptMallocZonesForTesting();
85*635a8641SAndroid Build Coastguard Worker #endif
86*635a8641SAndroid Build Coastguard Worker }
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_MACOSX)
89*635a8641SAndroid Build Coastguard Worker
TEST(MemoryTest,AllocatorShimWorking)90*635a8641SAndroid Build Coastguard Worker TEST(MemoryTest, AllocatorShimWorking) {
91*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
92*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(USE_ALLOCATOR_SHIM)
93*635a8641SAndroid Build Coastguard Worker base::allocator::InitializeAllocatorShim();
94*635a8641SAndroid Build Coastguard Worker #endif
95*635a8641SAndroid Build Coastguard Worker base::allocator::InterceptAllocationsMac();
96*635a8641SAndroid Build Coastguard Worker #endif
97*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(base::allocator::IsAllocatorInitialized());
98*635a8641SAndroid Build Coastguard Worker
99*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
100*635a8641SAndroid Build Coastguard Worker base::allocator::UninterceptMallocZonesForTesting();
101*635a8641SAndroid Build Coastguard Worker #endif
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker
104*635a8641SAndroid Build Coastguard Worker // OpenBSD does not support these tests. Don't test these on ASan/TSan/MSan
105*635a8641SAndroid Build Coastguard Worker // configurations: only test the real allocator.
106*635a8641SAndroid Build Coastguard Worker // Windows only supports these tests with the allocator shim in place.
107*635a8641SAndroid Build Coastguard Worker #if !defined(OS_OPENBSD) && BUILDFLAG(USE_ALLOCATOR_SHIM) && \
108*635a8641SAndroid Build Coastguard Worker !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker namespace {
111*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
112*635a8641SAndroid Build Coastguard Worker // Windows raises an exception rather than using LOG(FATAL) in order to make the
113*635a8641SAndroid Build Coastguard Worker // exit code unique to OOM.
114*635a8641SAndroid Build Coastguard Worker const char* kOomRegex = "";
115*635a8641SAndroid Build Coastguard Worker const int kExitCode = base::win::kOomExceptionCode;
116*635a8641SAndroid Build Coastguard Worker #else
117*635a8641SAndroid Build Coastguard Worker const char* kOomRegex = "Out of memory";
118*635a8641SAndroid Build Coastguard Worker const int kExitCode = 1;
119*635a8641SAndroid Build Coastguard Worker #endif
120*635a8641SAndroid Build Coastguard Worker } // namespace
121*635a8641SAndroid Build Coastguard Worker
122*635a8641SAndroid Build Coastguard Worker class OutOfMemoryTest : public testing::Test {
123*635a8641SAndroid Build Coastguard Worker public:
OutOfMemoryTest()124*635a8641SAndroid Build Coastguard Worker OutOfMemoryTest()
125*635a8641SAndroid Build Coastguard Worker : value_(nullptr),
126*635a8641SAndroid Build Coastguard Worker // Make test size as large as possible minus a few pages so
127*635a8641SAndroid Build Coastguard Worker // that alignment or other rounding doesn't make it wrap.
128*635a8641SAndroid Build Coastguard Worker test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024),
129*635a8641SAndroid Build Coastguard Worker // A test size that is > 2Gb and will cause the allocators to reject
130*635a8641SAndroid Build Coastguard Worker // the allocation due to security restrictions. See crbug.com/169327.
131*635a8641SAndroid Build Coastguard Worker insecure_test_size_(std::numeric_limits<int>::max()),
132*635a8641SAndroid Build Coastguard Worker signed_test_size_(std::numeric_limits<ssize_t>::max()) {}
133*635a8641SAndroid Build Coastguard Worker
134*635a8641SAndroid Build Coastguard Worker protected:
135*635a8641SAndroid Build Coastguard Worker void* value_;
136*635a8641SAndroid Build Coastguard Worker size_t test_size_;
137*635a8641SAndroid Build Coastguard Worker size_t insecure_test_size_;
138*635a8641SAndroid Build Coastguard Worker ssize_t signed_test_size_;
139*635a8641SAndroid Build Coastguard Worker };
140*635a8641SAndroid Build Coastguard Worker
141*635a8641SAndroid Build Coastguard Worker class OutOfMemoryDeathTest : public OutOfMemoryTest {
142*635a8641SAndroid Build Coastguard Worker public:
SetUpInDeathAssert()143*635a8641SAndroid Build Coastguard Worker void SetUpInDeathAssert() {
144*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX) && BUILDFLAG(USE_ALLOCATOR_SHIM)
145*635a8641SAndroid Build Coastguard Worker base::allocator::InitializeAllocatorShim();
146*635a8641SAndroid Build Coastguard Worker #endif
147*635a8641SAndroid Build Coastguard Worker
148*635a8641SAndroid Build Coastguard Worker // Must call EnableTerminationOnOutOfMemory() because that is called from
149*635a8641SAndroid Build Coastguard Worker // chrome's main function and therefore hasn't been called yet.
150*635a8641SAndroid Build Coastguard Worker // Since this call may result in another thread being created and death
151*635a8641SAndroid Build Coastguard Worker // tests shouldn't be started in a multithread environment, this call
152*635a8641SAndroid Build Coastguard Worker // should be done inside of the ASSERT_DEATH.
153*635a8641SAndroid Build Coastguard Worker base::EnableTerminationOnOutOfMemory();
154*635a8641SAndroid Build Coastguard Worker }
155*635a8641SAndroid Build Coastguard Worker
156*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
TearDown()157*635a8641SAndroid Build Coastguard Worker void TearDown() override {
158*635a8641SAndroid Build Coastguard Worker base::allocator::UninterceptMallocZonesForTesting();
159*635a8641SAndroid Build Coastguard Worker }
160*635a8641SAndroid Build Coastguard Worker #endif
161*635a8641SAndroid Build Coastguard Worker };
162*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,New)163*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, New) {
164*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
165*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
166*635a8641SAndroid Build Coastguard Worker value_ = operator new(test_size_);
167*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
168*635a8641SAndroid Build Coastguard Worker }
169*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,NewArray)170*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, NewArray) {
171*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
172*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
173*635a8641SAndroid Build Coastguard Worker value_ = new char[test_size_];
174*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
175*635a8641SAndroid Build Coastguard Worker }
176*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,Malloc)177*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Malloc) {
178*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
179*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
180*635a8641SAndroid Build Coastguard Worker value_ = malloc(test_size_);
181*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
182*635a8641SAndroid Build Coastguard Worker }
183*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,Realloc)184*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Realloc) {
185*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
186*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
187*635a8641SAndroid Build Coastguard Worker value_ = realloc(nullptr, test_size_);
188*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
189*635a8641SAndroid Build Coastguard Worker }
190*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,Calloc)191*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Calloc) {
192*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
193*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
194*635a8641SAndroid Build Coastguard Worker value_ = calloc(1024, test_size_ / 1024L);
195*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
196*635a8641SAndroid Build Coastguard Worker }
197*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,AlignedAlloc)198*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, AlignedAlloc) {
199*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
200*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
201*635a8641SAndroid Build Coastguard Worker value_ = base::AlignedAlloc(test_size_, 8);
202*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
203*635a8641SAndroid Build Coastguard Worker }
204*635a8641SAndroid Build Coastguard Worker
205*635a8641SAndroid Build Coastguard Worker // POSIX does not define an aligned realloc function.
206*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
TEST_F(OutOfMemoryDeathTest,AlignedRealloc)207*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, AlignedRealloc) {
208*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
209*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
210*635a8641SAndroid Build Coastguard Worker value_ = _aligned_realloc(NULL, test_size_, 8);
211*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
212*635a8641SAndroid Build Coastguard Worker }
213*635a8641SAndroid Build Coastguard Worker
214*635a8641SAndroid Build Coastguard Worker namespace {
215*635a8641SAndroid Build Coastguard Worker
216*635a8641SAndroid Build Coastguard Worker constexpr uint32_t kUnhandledExceptionExitCode = 0xBADA55;
217*635a8641SAndroid Build Coastguard Worker
218*635a8641SAndroid Build Coastguard Worker // This unhandled exception filter exits the process with an exit code distinct
219*635a8641SAndroid Build Coastguard Worker // from the exception code. This is to verify that the out of memory new handler
220*635a8641SAndroid Build Coastguard Worker // causes an unhandled exception.
ExitingUnhandledExceptionFilter(EXCEPTION_POINTERS * ExceptionInfo)221*635a8641SAndroid Build Coastguard Worker LONG WINAPI ExitingUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo) {
222*635a8641SAndroid Build Coastguard Worker _exit(kUnhandledExceptionExitCode);
223*635a8641SAndroid Build Coastguard Worker }
224*635a8641SAndroid Build Coastguard Worker
225*635a8641SAndroid Build Coastguard Worker } // namespace
226*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,NewHandlerGeneratesUnhandledException)227*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, NewHandlerGeneratesUnhandledException) {
228*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT(
229*635a8641SAndroid Build Coastguard Worker {
230*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
231*635a8641SAndroid Build Coastguard Worker SetUnhandledExceptionFilter(&ExitingUnhandledExceptionFilter);
232*635a8641SAndroid Build Coastguard Worker value_ = new char[test_size_];
233*635a8641SAndroid Build Coastguard Worker },
234*635a8641SAndroid Build Coastguard Worker testing::ExitedWithCode(kUnhandledExceptionExitCode), kOomRegex);
235*635a8641SAndroid Build Coastguard Worker }
236*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_WIN)
237*635a8641SAndroid Build Coastguard Worker
238*635a8641SAndroid Build Coastguard Worker // OS X and Android have no 2Gb allocation limit.
239*635a8641SAndroid Build Coastguard Worker // See https://crbug.com/169327.
240*635a8641SAndroid Build Coastguard Worker #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
TEST_F(OutOfMemoryDeathTest,SecurityNew)241*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityNew) {
242*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
243*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
244*635a8641SAndroid Build Coastguard Worker value_ = operator new(insecure_test_size_);
245*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
246*635a8641SAndroid Build Coastguard Worker }
247*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityNewArray)248*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityNewArray) {
249*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
250*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
251*635a8641SAndroid Build Coastguard Worker value_ = new char[insecure_test_size_];
252*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
253*635a8641SAndroid Build Coastguard Worker }
254*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityMalloc)255*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityMalloc) {
256*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
257*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
258*635a8641SAndroid Build Coastguard Worker value_ = malloc(insecure_test_size_);
259*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
260*635a8641SAndroid Build Coastguard Worker }
261*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityRealloc)262*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityRealloc) {
263*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
264*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
265*635a8641SAndroid Build Coastguard Worker value_ = realloc(nullptr, insecure_test_size_);
266*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
267*635a8641SAndroid Build Coastguard Worker }
268*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityCalloc)269*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityCalloc) {
270*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
271*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
272*635a8641SAndroid Build Coastguard Worker value_ = calloc(1024, insecure_test_size_ / 1024L);
273*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
274*635a8641SAndroid Build Coastguard Worker }
275*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityAlignedAlloc)276*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityAlignedAlloc) {
277*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
278*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
279*635a8641SAndroid Build Coastguard Worker value_ = base::AlignedAlloc(insecure_test_size_, 8);
280*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
281*635a8641SAndroid Build Coastguard Worker }
282*635a8641SAndroid Build Coastguard Worker
283*635a8641SAndroid Build Coastguard Worker // POSIX does not define an aligned realloc function.
284*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
TEST_F(OutOfMemoryDeathTest,SecurityAlignedRealloc)285*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityAlignedRealloc) {
286*635a8641SAndroid Build Coastguard Worker ASSERT_EXIT({
287*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
288*635a8641SAndroid Build Coastguard Worker value_ = _aligned_realloc(NULL, insecure_test_size_, 8);
289*635a8641SAndroid Build Coastguard Worker }, testing::ExitedWithCode(kExitCode), kOomRegex);
290*635a8641SAndroid Build Coastguard Worker }
291*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_WIN)
292*635a8641SAndroid Build Coastguard Worker #endif // !defined(OS_MACOSX) && !defined(OS_ANDROID)
293*635a8641SAndroid Build Coastguard Worker
294*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
295*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,Valloc)296*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Valloc) {
297*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
298*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
299*635a8641SAndroid Build Coastguard Worker value_ = valloc(test_size_);
300*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
301*635a8641SAndroid Build Coastguard Worker }
302*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityValloc)303*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityValloc) {
304*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
305*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
306*635a8641SAndroid Build Coastguard Worker value_ = valloc(insecure_test_size_);
307*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
308*635a8641SAndroid Build Coastguard Worker }
309*635a8641SAndroid Build Coastguard Worker
310*635a8641SAndroid Build Coastguard Worker #if PVALLOC_AVAILABLE == 1
TEST_F(OutOfMemoryDeathTest,Pvalloc)311*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Pvalloc) {
312*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
313*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
314*635a8641SAndroid Build Coastguard Worker value_ = pvalloc(test_size_);
315*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
316*635a8641SAndroid Build Coastguard Worker }
317*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,SecurityPvalloc)318*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, SecurityPvalloc) {
319*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
320*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
321*635a8641SAndroid Build Coastguard Worker value_ = pvalloc(insecure_test_size_);
322*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
323*635a8641SAndroid Build Coastguard Worker }
324*635a8641SAndroid Build Coastguard Worker #endif // PVALLOC_AVAILABLE == 1
325*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,Memalign)326*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Memalign) {
327*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
328*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
329*635a8641SAndroid Build Coastguard Worker value_ = memalign(4, test_size_);
330*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
331*635a8641SAndroid Build Coastguard Worker }
332*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,ViaSharedLibraries)333*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, ViaSharedLibraries) {
334*635a8641SAndroid Build Coastguard Worker // This tests that the run-time symbol resolution is overriding malloc for
335*635a8641SAndroid Build Coastguard Worker // shared libraries as well as for our code.
336*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
337*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
338*635a8641SAndroid Build Coastguard Worker value_ = MallocWrapper(test_size_);
339*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
340*635a8641SAndroid Build Coastguard Worker }
341*635a8641SAndroid Build Coastguard Worker #endif // OS_LINUX
342*635a8641SAndroid Build Coastguard Worker
343*635a8641SAndroid Build Coastguard Worker // Android doesn't implement posix_memalign().
344*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) && !defined(OS_ANDROID)
TEST_F(OutOfMemoryDeathTest,Posix_memalign)345*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, Posix_memalign) {
346*635a8641SAndroid Build Coastguard Worker // Grab the return value of posix_memalign to silence a compiler warning
347*635a8641SAndroid Build Coastguard Worker // about unused return values. We don't actually care about the return
348*635a8641SAndroid Build Coastguard Worker // value, since we're asserting death.
349*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
350*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
351*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ENOMEM, posix_memalign(&value_, 8, test_size_));
352*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
353*635a8641SAndroid Build Coastguard Worker }
354*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_POSIX) && !defined(OS_ANDROID)
355*635a8641SAndroid Build Coastguard Worker
356*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
357*635a8641SAndroid Build Coastguard Worker
358*635a8641SAndroid Build Coastguard Worker // Purgeable zone tests
359*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,MallocPurgeable)360*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, MallocPurgeable) {
361*635a8641SAndroid Build Coastguard Worker malloc_zone_t* zone = malloc_default_purgeable_zone();
362*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
363*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
364*635a8641SAndroid Build Coastguard Worker value_ = malloc_zone_malloc(zone, test_size_);
365*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
366*635a8641SAndroid Build Coastguard Worker }
367*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,ReallocPurgeable)368*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, ReallocPurgeable) {
369*635a8641SAndroid Build Coastguard Worker malloc_zone_t* zone = malloc_default_purgeable_zone();
370*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
371*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
372*635a8641SAndroid Build Coastguard Worker value_ = malloc_zone_realloc(zone, NULL, test_size_);
373*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
374*635a8641SAndroid Build Coastguard Worker }
375*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,CallocPurgeable)376*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, CallocPurgeable) {
377*635a8641SAndroid Build Coastguard Worker malloc_zone_t* zone = malloc_default_purgeable_zone();
378*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
379*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
380*635a8641SAndroid Build Coastguard Worker value_ = malloc_zone_calloc(zone, 1024, test_size_ / 1024L);
381*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
382*635a8641SAndroid Build Coastguard Worker }
383*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,VallocPurgeable)384*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, VallocPurgeable) {
385*635a8641SAndroid Build Coastguard Worker malloc_zone_t* zone = malloc_default_purgeable_zone();
386*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
387*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
388*635a8641SAndroid Build Coastguard Worker value_ = malloc_zone_valloc(zone, test_size_);
389*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
390*635a8641SAndroid Build Coastguard Worker }
391*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,PosixMemalignPurgeable)392*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, PosixMemalignPurgeable) {
393*635a8641SAndroid Build Coastguard Worker malloc_zone_t* zone = malloc_default_purgeable_zone();
394*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
395*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
396*635a8641SAndroid Build Coastguard Worker value_ = malloc_zone_memalign(zone, 8, test_size_);
397*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
398*635a8641SAndroid Build Coastguard Worker }
399*635a8641SAndroid Build Coastguard Worker
400*635a8641SAndroid Build Coastguard Worker // Since these allocation functions take a signed size, it's possible that
401*635a8641SAndroid Build Coastguard Worker // calling them just once won't be enough to exhaust memory. In the 32-bit
402*635a8641SAndroid Build Coastguard Worker // environment, it's likely that these allocation attempts will fail because
403*635a8641SAndroid Build Coastguard Worker // not enough contiguous address space is available. In the 64-bit environment,
404*635a8641SAndroid Build Coastguard Worker // it's likely that they'll fail because they would require a preposterous
405*635a8641SAndroid Build Coastguard Worker // amount of (virtual) memory.
406*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,CFAllocatorSystemDefault)407*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, CFAllocatorSystemDefault) {
408*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
409*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
410*635a8641SAndroid Build Coastguard Worker while ((value_ =
411*635a8641SAndroid Build Coastguard Worker base::AllocateViaCFAllocatorSystemDefault(signed_test_size_))) {}
412*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
413*635a8641SAndroid Build Coastguard Worker }
414*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,CFAllocatorMalloc)415*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, CFAllocatorMalloc) {
416*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
417*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
418*635a8641SAndroid Build Coastguard Worker while ((value_ =
419*635a8641SAndroid Build Coastguard Worker base::AllocateViaCFAllocatorMalloc(signed_test_size_))) {}
420*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
421*635a8641SAndroid Build Coastguard Worker }
422*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,CFAllocatorMallocZone)423*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, CFAllocatorMallocZone) {
424*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
425*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
426*635a8641SAndroid Build Coastguard Worker while ((value_ =
427*635a8641SAndroid Build Coastguard Worker base::AllocateViaCFAllocatorMallocZone(signed_test_size_))) {}
428*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
429*635a8641SAndroid Build Coastguard Worker }
430*635a8641SAndroid Build Coastguard Worker
431*635a8641SAndroid Build Coastguard Worker #if !defined(ARCH_CPU_64_BITS)
432*635a8641SAndroid Build Coastguard Worker
433*635a8641SAndroid Build Coastguard Worker // See process_util_unittest_mac.mm for an explanation of why this test isn't
434*635a8641SAndroid Build Coastguard Worker // run in the 64-bit environment.
435*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryDeathTest,PsychoticallyBigObjCObject)436*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryDeathTest, PsychoticallyBigObjCObject) {
437*635a8641SAndroid Build Coastguard Worker ASSERT_DEATH({
438*635a8641SAndroid Build Coastguard Worker SetUpInDeathAssert();
439*635a8641SAndroid Build Coastguard Worker while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {}
440*635a8641SAndroid Build Coastguard Worker }, kOomRegex);
441*635a8641SAndroid Build Coastguard Worker }
442*635a8641SAndroid Build Coastguard Worker
443*635a8641SAndroid Build Coastguard Worker #endif // !ARCH_CPU_64_BITS
444*635a8641SAndroid Build Coastguard Worker #endif // OS_MACOSX
445*635a8641SAndroid Build Coastguard Worker
446*635a8641SAndroid Build Coastguard Worker class OutOfMemoryHandledTest : public OutOfMemoryTest {
447*635a8641SAndroid Build Coastguard Worker public:
448*635a8641SAndroid Build Coastguard Worker static const size_t kSafeMallocSize = 512;
449*635a8641SAndroid Build Coastguard Worker static const size_t kSafeCallocSize = 128;
450*635a8641SAndroid Build Coastguard Worker static const size_t kSafeCallocItems = 4;
451*635a8641SAndroid Build Coastguard Worker
SetUp()452*635a8641SAndroid Build Coastguard Worker void SetUp() override {
453*635a8641SAndroid Build Coastguard Worker OutOfMemoryTest::SetUp();
454*635a8641SAndroid Build Coastguard Worker
455*635a8641SAndroid Build Coastguard Worker // We enable termination on OOM - just as Chrome does at early
456*635a8641SAndroid Build Coastguard Worker // initialization - and test that UncheckedMalloc and UncheckedCalloc
457*635a8641SAndroid Build Coastguard Worker // properly by-pass this in order to allow the caller to handle OOM.
458*635a8641SAndroid Build Coastguard Worker base::EnableTerminationOnOutOfMemory();
459*635a8641SAndroid Build Coastguard Worker }
460*635a8641SAndroid Build Coastguard Worker
TearDown()461*635a8641SAndroid Build Coastguard Worker void TearDown() override {
462*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
463*635a8641SAndroid Build Coastguard Worker base::allocator::UninterceptMallocZonesForTesting();
464*635a8641SAndroid Build Coastguard Worker #endif
465*635a8641SAndroid Build Coastguard Worker }
466*635a8641SAndroid Build Coastguard Worker };
467*635a8641SAndroid Build Coastguard Worker
468*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
469*635a8641SAndroid Build Coastguard Worker
470*635a8641SAndroid Build Coastguard Worker namespace {
471*635a8641SAndroid Build Coastguard Worker
HandleOutOfMemoryException(EXCEPTION_POINTERS * exception_ptrs,size_t expected_size)472*635a8641SAndroid Build Coastguard Worker DWORD HandleOutOfMemoryException(EXCEPTION_POINTERS* exception_ptrs,
473*635a8641SAndroid Build Coastguard Worker size_t expected_size) {
474*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(base::win::kOomExceptionCode,
475*635a8641SAndroid Build Coastguard Worker exception_ptrs->ExceptionRecord->ExceptionCode);
476*635a8641SAndroid Build Coastguard Worker EXPECT_LE(1U, exception_ptrs->ExceptionRecord->NumberParameters);
477*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_size,
478*635a8641SAndroid Build Coastguard Worker exception_ptrs->ExceptionRecord->ExceptionInformation[0]);
479*635a8641SAndroid Build Coastguard Worker return EXCEPTION_EXECUTE_HANDLER;
480*635a8641SAndroid Build Coastguard Worker }
481*635a8641SAndroid Build Coastguard Worker
482*635a8641SAndroid Build Coastguard Worker } // namespace
483*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryTest,TerminateBecauseOutOfMemoryReportsAllocSize)484*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryTest, TerminateBecauseOutOfMemoryReportsAllocSize) {
485*635a8641SAndroid Build Coastguard Worker // On Windows, TerminateBecauseOutOfMemory reports the attempted allocation
486*635a8641SAndroid Build Coastguard Worker // size in the exception raised.
487*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_64_BITS)
488*635a8641SAndroid Build Coastguard Worker // Test with a size larger than 32 bits on 64 bit machines.
489*635a8641SAndroid Build Coastguard Worker const size_t kAttemptedAllocationSize = 0xBADA55F00DULL;
490*635a8641SAndroid Build Coastguard Worker #else
491*635a8641SAndroid Build Coastguard Worker const size_t kAttemptedAllocationSize = 0xBADA55;
492*635a8641SAndroid Build Coastguard Worker #endif
493*635a8641SAndroid Build Coastguard Worker
494*635a8641SAndroid Build Coastguard Worker __try {
495*635a8641SAndroid Build Coastguard Worker base::TerminateBecauseOutOfMemory(kAttemptedAllocationSize);
496*635a8641SAndroid Build Coastguard Worker } __except (HandleOutOfMemoryException(GetExceptionInformation(),
497*635a8641SAndroid Build Coastguard Worker kAttemptedAllocationSize)) {
498*635a8641SAndroid Build Coastguard Worker }
499*635a8641SAndroid Build Coastguard Worker }
500*635a8641SAndroid Build Coastguard Worker #endif // OS_WIN
501*635a8641SAndroid Build Coastguard Worker
502*635a8641SAndroid Build Coastguard Worker // TODO(b.kelemen): make UncheckedMalloc and UncheckedCalloc work
503*635a8641SAndroid Build Coastguard Worker // on Windows as well.
TEST_F(OutOfMemoryHandledTest,UncheckedMalloc)504*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryHandledTest, UncheckedMalloc) {
505*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(base::UncheckedMalloc(kSafeMallocSize, &value_));
506*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value_ != nullptr);
507*635a8641SAndroid Build Coastguard Worker free(value_);
508*635a8641SAndroid Build Coastguard Worker
509*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(base::UncheckedMalloc(test_size_, &value_));
510*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value_ == nullptr);
511*635a8641SAndroid Build Coastguard Worker }
512*635a8641SAndroid Build Coastguard Worker
TEST_F(OutOfMemoryHandledTest,UncheckedCalloc)513*635a8641SAndroid Build Coastguard Worker TEST_F(OutOfMemoryHandledTest, UncheckedCalloc) {
514*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(base::UncheckedCalloc(1, kSafeMallocSize, &value_));
515*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value_ != nullptr);
516*635a8641SAndroid Build Coastguard Worker const char* bytes = static_cast<const char*>(value_);
517*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kSafeMallocSize; ++i)
518*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, bytes[i]);
519*635a8641SAndroid Build Coastguard Worker free(value_);
520*635a8641SAndroid Build Coastguard Worker
521*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(
522*635a8641SAndroid Build Coastguard Worker base::UncheckedCalloc(kSafeCallocItems, kSafeCallocSize, &value_));
523*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value_ != nullptr);
524*635a8641SAndroid Build Coastguard Worker bytes = static_cast<const char*>(value_);
525*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < (kSafeCallocItems * kSafeCallocSize); ++i)
526*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, bytes[i]);
527*635a8641SAndroid Build Coastguard Worker free(value_);
528*635a8641SAndroid Build Coastguard Worker
529*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(base::UncheckedCalloc(1, test_size_, &value_));
530*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(value_ == nullptr);
531*635a8641SAndroid Build Coastguard Worker }
532*635a8641SAndroid Build Coastguard Worker #endif // !defined(OS_OPENBSD) && BUILDFLAG(ENABLE_WIN_ALLOCATOR_SHIM_TESTS) &&
533*635a8641SAndroid Build Coastguard Worker // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
534