diff options
author | Mitch Phillips <mitchp@google.com> | 2021-01-20 16:03:27 -0800 |
---|---|---|
committer | Mitch Phillips <mitchp@google.com> | 2021-01-25 15:19:31 -0800 |
commit | 9cad8424ff7b0fa63b53cb9919eae31539b8561a (patch) | |
tree | f7998255ede5ce02dc6406f7e40f9ac70b4c37ed /tests/malloc_test.cpp | |
parent | d65b31fad659b806401201adb3cd1dcbf38e61e3 (diff) |
[MemInit] Remove old API, introduce new MemInit API.
Introduces new heap-zero-init API. We've realised that it's better to be
able to individually control MTE and heap zero-init. Having
heap-zero-init not be controllable without affecting MTE affects our
ability to turn off heap-zero-init in zygote-forked applications.
Bug: 135772972
Test: On FVP: atest -s localhost:5555 malloc#zero_init \
Test: malloc#disable_mte heap_tagging_level
Change-Id: I8c6722502733259934c699f4f1269eaf1641a09f
Diffstat (limited to 'tests/malloc_test.cpp')
-rw-r--r-- | tests/malloc_test.cpp | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp index b35bba983..3a09258f7 100644 --- a/tests/malloc_test.cpp +++ b/tests/malloc_test.cpp @@ -32,8 +32,10 @@ #include <sys/wait.h> #include <unistd.h> +#include <algorithm> #include <atomic> #include <thread> +#include <vector> #include <tinyxml2.h> @@ -1256,7 +1258,67 @@ TEST(android_mallopt, set_allocation_limit_multiple_threads) { #endif } -TEST(malloc, disable_memory_mitigations) { +void TestHeapZeroing(int num_iterations, int (*get_alloc_size)(int iteration)) { + std::vector<void*> allocs; + constexpr int kMaxBytesToCheckZero = 64; + const char kBlankMemory[kMaxBytesToCheckZero] = {}; + + for (int i = 0; i < num_iterations; ++i) { + int size = get_alloc_size(i); + allocs.push_back(malloc(size)); + memset(allocs.back(), 'X', std::min(size, kMaxBytesToCheckZero)); + } + + for (void* alloc : allocs) { + free(alloc); + } + allocs.clear(); + + for (int i = 0; i < num_iterations; ++i) { + int size = get_alloc_size(i); + allocs.push_back(malloc(size)); + ASSERT_EQ(0, memcmp(allocs.back(), kBlankMemory, std::min(size, kMaxBytesToCheckZero))); + } + + for (void* alloc : allocs) { + free(alloc); + } +} + +TEST(malloc, zero_init) { +#if defined(__BIONIC__) + SKIP_WITH_HWASAN << "hwasan does not implement mallopt"; + bool allocator_scudo; + GetAllocatorVersion(&allocator_scudo); + if (!allocator_scudo) { + GTEST_SKIP() << "scudo allocator only test"; + } + + mallopt(M_BIONIC_ZERO_INIT, 1); + + // Test using a block of 4K small (1-32 byte) allocations. + TestHeapZeroing(/* num_iterations */ 0x1000, [](int iteration) -> int { + return 1 + iteration % 32; + }); + + // Also test large allocations that land in the scudo secondary, as this is + // the only part of Scudo that's changed by enabling zero initialization with + // MTE. Uses 32 allocations, totalling 60MiB memory. Decay time (time to + // release secondary allocations back to the OS) was modified to 0ms/1ms by + // mallopt_decay. Ensure that we delay for at least a second before releasing + // pages to the OS in order to avoid implicit zeroing by the kernel. + mallopt(M_DECAY_TIME, 1000); + TestHeapZeroing(/* num_iterations */ 32, [](int iteration) -> int { + return 1 << (19 + iteration % 4); + }); + +#else + GTEST_SKIP() << "bionic-only test"; +#endif +} + +// Note that MTE is enabled on cc_tests on devices that support MTE. +TEST(malloc, disable_mte) { #if defined(__BIONIC__) if (!mte_supported()) { GTEST_SKIP() << "This function can only be tested with MTE"; @@ -1275,7 +1337,7 @@ TEST(malloc, disable_memory_mitigations) { }, &sem)); - ASSERT_EQ(1, mallopt(M_BIONIC_DISABLE_MEMORY_MITIGATIONS, 0)); + ASSERT_EQ(1, mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_NONE)); ASSERT_EQ(0, sem_post(&sem)); int my_tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0); |