1 //===-- never_allocated.cpp -------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <string> 10 11 #include "gwp_asan/common.h" 12 #include "gwp_asan/crash_handler.h" 13 #include "gwp_asan/tests/harness.h" 14 TEST_P(BacktraceGuardedPoolAllocatorDeathTest,NeverAllocated)15TEST_P(BacktraceGuardedPoolAllocatorDeathTest, NeverAllocated) { 16 SCOPED_TRACE(""); 17 void *Ptr = GPA.allocate(0x1000); 18 GPA.deallocate(Ptr); 19 20 std::string DeathNeedle = 21 "GWP-ASan cannot provide any more information about this error"; 22 23 // Trigger a guard page in a completely different slot that's never allocated. 24 // Previously, there was a bug that this would result in nullptr-dereference 25 // in the posix crash handler. 26 char *volatile NeverAllocatedPtr = static_cast<char *>(Ptr) + 0x3000; 27 if (!Recoverable) { 28 EXPECT_DEATH(*NeverAllocatedPtr = 0, DeathNeedle); 29 return; 30 } 31 32 *NeverAllocatedPtr = 0; 33 CheckOnlyOneGwpAsanCrash(GetOutputBuffer()); 34 ASSERT_NE(std::string::npos, GetOutputBuffer().find(DeathNeedle)); 35 36 // Check that subsequent invalid touches of the pool don't print a report. 37 GetOutputBuffer().clear(); 38 for (size_t i = 0; i < 100; ++i) { 39 *NeverAllocatedPtr = 0; 40 *(NeverAllocatedPtr + 0x2000) = 0; 41 *(NeverAllocatedPtr + 0x3000) = 0; 42 ASSERT_TRUE(GetOutputBuffer().empty()); 43 } 44 45 // Check that reports on the other slots still report a double-free, but only 46 // once. 47 GetOutputBuffer().clear(); 48 GPA.deallocate(Ptr); 49 ASSERT_NE(std::string::npos, GetOutputBuffer().find("Double Free")); 50 GetOutputBuffer().clear(); 51 for (size_t i = 0; i < 100; ++i) { 52 DeallocateMemory(GPA, Ptr); 53 ASSERT_TRUE(GetOutputBuffer().empty()); 54 } 55 } 56