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