xref: /llvm-project/compiler-rt/lib/gwp_asan/tests/never_allocated.cpp (revision f2a1726d2199150918430a84f29cf8835bfe8e5a)
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 Phillips TEST_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