xref: /llvm-project/compiler-rt/lib/gwp_asan/tests/slot_reuse.cpp (revision 5556616b5b5223f95607ad94053a55f0deaf2762)
14a1a113aSNico Weber //===-- slot_reuse.cpp ------------------------------------------*- C++ -*-===//
2a95edb9dSMitch Phillips //
3a95edb9dSMitch Phillips // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a95edb9dSMitch Phillips // See https://llvm.org/LICENSE.txt for license information.
5a95edb9dSMitch Phillips // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a95edb9dSMitch Phillips //
7a95edb9dSMitch Phillips //===----------------------------------------------------------------------===//
8a95edb9dSMitch Phillips 
9a95edb9dSMitch Phillips #include "gwp_asan/tests/harness.h"
10a95edb9dSMitch Phillips 
11*5556616bSKostya Kortchinsky #include <set>
12*5556616bSKostya Kortchinsky 
singleByteGoodAllocDealloc(gwp_asan::GuardedPoolAllocator * GPA)13a95edb9dSMitch Phillips void singleByteGoodAllocDealloc(gwp_asan::GuardedPoolAllocator *GPA) {
14a95edb9dSMitch Phillips   void *Ptr = GPA->allocate(1);
15a95edb9dSMitch Phillips   EXPECT_NE(nullptr, Ptr);
16a95edb9dSMitch Phillips   EXPECT_TRUE(GPA->pointerIsMine(Ptr));
17a95edb9dSMitch Phillips   EXPECT_EQ(1u, GPA->getSize(Ptr));
18a95edb9dSMitch Phillips   GPA->deallocate(Ptr);
19a95edb9dSMitch Phillips }
20a95edb9dSMitch Phillips 
TEST_F(CustomGuardedPoolAllocator,EnsureReuseOfQuarantine1)21a95edb9dSMitch Phillips TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine1) {
22a95edb9dSMitch Phillips   InitNumSlots(1);
23a95edb9dSMitch Phillips   for (unsigned i = 0; i < 128; ++i)
24a95edb9dSMitch Phillips     singleByteGoodAllocDealloc(&GPA);
25a95edb9dSMitch Phillips }
26a95edb9dSMitch Phillips 
TEST_F(CustomGuardedPoolAllocator,EnsureReuseOfQuarantine2)27a95edb9dSMitch Phillips TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine2) {
28a95edb9dSMitch Phillips   InitNumSlots(2);
29a95edb9dSMitch Phillips   for (unsigned i = 0; i < 128; ++i)
30a95edb9dSMitch Phillips     singleByteGoodAllocDealloc(&GPA);
31a95edb9dSMitch Phillips }
32a95edb9dSMitch Phillips 
TEST_F(CustomGuardedPoolAllocator,EnsureReuseOfQuarantine127)33a95edb9dSMitch Phillips TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine127) {
34a95edb9dSMitch Phillips   InitNumSlots(127);
35a95edb9dSMitch Phillips   for (unsigned i = 0; i < 128; ++i)
36a95edb9dSMitch Phillips     singleByteGoodAllocDealloc(&GPA);
37a95edb9dSMitch Phillips }
38a95edb9dSMitch Phillips 
39a95edb9dSMitch Phillips // This test ensures that our slots are not reused ahead of time. We increase
40a95edb9dSMitch Phillips // the use-after-free detection by not reusing slots until all of them have been
41a95edb9dSMitch Phillips // allocated. This is done by always using the slots from left-to-right in the
42a95edb9dSMitch Phillips // pool before we used each slot once, at which point random selection takes
43a95edb9dSMitch Phillips // over.
runNoReuseBeforeNecessary(gwp_asan::GuardedPoolAllocator * GPA,unsigned PoolSize)44a95edb9dSMitch Phillips void runNoReuseBeforeNecessary(gwp_asan::GuardedPoolAllocator *GPA,
45a95edb9dSMitch Phillips                                unsigned PoolSize) {
46a95edb9dSMitch Phillips   std::set<void *> Ptrs;
47a95edb9dSMitch Phillips   for (unsigned i = 0; i < PoolSize; ++i) {
48a95edb9dSMitch Phillips     void *Ptr = GPA->allocate(1);
49a95edb9dSMitch Phillips 
50a95edb9dSMitch Phillips     EXPECT_TRUE(GPA->pointerIsMine(Ptr));
51a95edb9dSMitch Phillips     EXPECT_EQ(0u, Ptrs.count(Ptr));
52a95edb9dSMitch Phillips 
53a95edb9dSMitch Phillips     Ptrs.insert(Ptr);
54a95edb9dSMitch Phillips     GPA->deallocate(Ptr);
55a95edb9dSMitch Phillips   }
56a95edb9dSMitch Phillips }
57a95edb9dSMitch Phillips 
TEST_F(CustomGuardedPoolAllocator,NoReuseBeforeNecessary2)58a95edb9dSMitch Phillips TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary2) {
59a95edb9dSMitch Phillips   constexpr unsigned kPoolSize = 2;
60a95edb9dSMitch Phillips   InitNumSlots(kPoolSize);
61a95edb9dSMitch Phillips   runNoReuseBeforeNecessary(&GPA, kPoolSize);
62a95edb9dSMitch Phillips }
63a95edb9dSMitch Phillips 
TEST_F(CustomGuardedPoolAllocator,NoReuseBeforeNecessary128)64a95edb9dSMitch Phillips TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary128) {
65a95edb9dSMitch Phillips   constexpr unsigned kPoolSize = 128;
66a95edb9dSMitch Phillips   InitNumSlots(kPoolSize);
67a95edb9dSMitch Phillips   runNoReuseBeforeNecessary(&GPA, kPoolSize);
68a95edb9dSMitch Phillips }
69a95edb9dSMitch Phillips 
TEST_F(CustomGuardedPoolAllocator,NoReuseBeforeNecessary129)70a95edb9dSMitch Phillips TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary129) {
71a95edb9dSMitch Phillips   constexpr unsigned kPoolSize = 129;
72a95edb9dSMitch Phillips   InitNumSlots(kPoolSize);
73a95edb9dSMitch Phillips   runNoReuseBeforeNecessary(&GPA, kPoolSize);
74a95edb9dSMitch Phillips }
75