xref: /openbsd-src/gnu/llvm/compiler-rt/lib/gwp_asan/tests/slot_reuse.cpp (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 //===-- slot_reuse.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 "gwp_asan/tests/harness.h"
10 
11 void singleByteGoodAllocDealloc(gwp_asan::GuardedPoolAllocator *GPA) {
12   void *Ptr = GPA->allocate(1);
13   EXPECT_NE(nullptr, Ptr);
14   EXPECT_TRUE(GPA->pointerIsMine(Ptr));
15   EXPECT_EQ(1u, GPA->getSize(Ptr));
16   GPA->deallocate(Ptr);
17 }
18 
19 TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine1) {
20   InitNumSlots(1);
21   for (unsigned i = 0; i < 128; ++i)
22     singleByteGoodAllocDealloc(&GPA);
23 }
24 
25 TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine2) {
26   InitNumSlots(2);
27   for (unsigned i = 0; i < 128; ++i)
28     singleByteGoodAllocDealloc(&GPA);
29 }
30 
31 TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine127) {
32   InitNumSlots(127);
33   for (unsigned i = 0; i < 128; ++i)
34     singleByteGoodAllocDealloc(&GPA);
35 }
36 
37 // This test ensures that our slots are not reused ahead of time. We increase
38 // the use-after-free detection by not reusing slots until all of them have been
39 // allocated. This is done by always using the slots from left-to-right in the
40 // pool before we used each slot once, at which point random selection takes
41 // over.
42 void runNoReuseBeforeNecessary(gwp_asan::GuardedPoolAllocator *GPA,
43                                unsigned PoolSize) {
44   std::set<void *> Ptrs;
45   for (unsigned i = 0; i < PoolSize; ++i) {
46     void *Ptr = GPA->allocate(1);
47 
48     EXPECT_TRUE(GPA->pointerIsMine(Ptr));
49     EXPECT_EQ(0u, Ptrs.count(Ptr));
50 
51     Ptrs.insert(Ptr);
52     GPA->deallocate(Ptr);
53   }
54 }
55 
56 TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary2) {
57   constexpr unsigned kPoolSize = 2;
58   InitNumSlots(kPoolSize);
59   runNoReuseBeforeNecessary(&GPA, kPoolSize);
60 }
61 
62 TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary128) {
63   constexpr unsigned kPoolSize = 128;
64   InitNumSlots(kPoolSize);
65   runNoReuseBeforeNecessary(&GPA, kPoolSize);
66 }
67 
68 TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary129) {
69   constexpr unsigned kPoolSize = 129;
70   InitNumSlots(kPoolSize);
71   runNoReuseBeforeNecessary(&GPA, kPoolSize);
72 }
73