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