xref: /llvm-project/compiler-rt/test/scudo/quarantine.c (revision f7c5c0d87b8ae5e55006fd3a31994cd68d64f102)
1*f7c5c0d8SMitch Phillips // RUN: %clang_scudo %s -o %t
2*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineSizeKb=64"           not %run %t unused 2>&1
3*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineChunksUpToSize=256"  not %run %t unused 2>&1
4*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0"     %run %t zeroquarantine 2>&1
5*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts=QuarantineSizeKb=64                                    %run %t smallquarantine 2>&1
6*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts=QuarantineChunksUpToSize=256                           %run %t threshold 2>&1
7*f7c5c0d8SMitch Phillips // RUN: %env_scudo_opts="QuarantineSizeMb=1"                                   %run %t oldquarantine 2>&1
8*f7c5c0d8SMitch Phillips 
9*f7c5c0d8SMitch Phillips // Tests that the quarantine prevents a chunk from being reused right away.
10*f7c5c0d8SMitch Phillips // Also tests that a chunk will eventually become available again for
11*f7c5c0d8SMitch Phillips // allocation when the recycling criteria has been met. Finally, tests the
12*f7c5c0d8SMitch Phillips // threshold up to which a chunk is quarantine, and the old quarantine behavior.
13*f7c5c0d8SMitch Phillips 
14*f7c5c0d8SMitch Phillips #include <assert.h>
15*f7c5c0d8SMitch Phillips #include <malloc.h>
16*f7c5c0d8SMitch Phillips #include <stdlib.h>
17*f7c5c0d8SMitch Phillips #include <string.h>
18*f7c5c0d8SMitch Phillips 
19*f7c5c0d8SMitch Phillips #include <sanitizer/allocator_interface.h>
20*f7c5c0d8SMitch Phillips 
main(int argc,char ** argv)21*f7c5c0d8SMitch Phillips int main(int argc, char **argv) {
22*f7c5c0d8SMitch Phillips   void *p, *old_p;
23*f7c5c0d8SMitch Phillips   size_t allocated_bytes, size = 1U << 8, alignment = 1U << 8;
24*f7c5c0d8SMitch Phillips 
25*f7c5c0d8SMitch Phillips   assert(argc == 2);
26*f7c5c0d8SMitch Phillips   // First, warm up the allocator for the classes used.
27*f7c5c0d8SMitch Phillips   p = malloc(size);
28*f7c5c0d8SMitch Phillips   assert(p);
29*f7c5c0d8SMitch Phillips   free(p);
30*f7c5c0d8SMitch Phillips   p = malloc(size + 1);
31*f7c5c0d8SMitch Phillips   assert(p);
32*f7c5c0d8SMitch Phillips   free(p);
33*f7c5c0d8SMitch Phillips   assert(posix_memalign(&p, alignment, size) == 0);
34*f7c5c0d8SMitch Phillips   assert(p);
35*f7c5c0d8SMitch Phillips   free(p);
36*f7c5c0d8SMitch Phillips   assert(posix_memalign(&p, alignment, size + 1) == 0);
37*f7c5c0d8SMitch Phillips   assert(p);
38*f7c5c0d8SMitch Phillips   free(p);
39*f7c5c0d8SMitch Phillips 
40*f7c5c0d8SMitch Phillips   if (!strcmp(argv[1], "zeroquarantine")) {
41*f7c5c0d8SMitch Phillips     // Verifies that a chunk is deallocated right away when the local and
42*f7c5c0d8SMitch Phillips     // global quarantine sizes are 0.
43*f7c5c0d8SMitch Phillips     allocated_bytes = __sanitizer_get_current_allocated_bytes();
44*f7c5c0d8SMitch Phillips     p = malloc(size);
45*f7c5c0d8SMitch Phillips     assert(p);
46*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
47*f7c5c0d8SMitch Phillips     free(p);
48*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);
49*f7c5c0d8SMitch Phillips   }
50*f7c5c0d8SMitch Phillips   if (!strcmp(argv[1], "smallquarantine")) {
51*f7c5c0d8SMitch Phillips     // The delayed freelist will prevent a chunk from being available right
52*f7c5c0d8SMitch Phillips     // away.
53*f7c5c0d8SMitch Phillips     p = malloc(size);
54*f7c5c0d8SMitch Phillips     assert(p);
55*f7c5c0d8SMitch Phillips     old_p = p;
56*f7c5c0d8SMitch Phillips     free(p);
57*f7c5c0d8SMitch Phillips     p = malloc(size);
58*f7c5c0d8SMitch Phillips     assert(p);
59*f7c5c0d8SMitch Phillips     assert(old_p != p);
60*f7c5c0d8SMitch Phillips     free(p);
61*f7c5c0d8SMitch Phillips 
62*f7c5c0d8SMitch Phillips     // Eventually the chunk should become available again.
63*f7c5c0d8SMitch Phillips     char found = 0;
64*f7c5c0d8SMitch Phillips     for (int i = 0; i < 0x200 && !found; i++) {
65*f7c5c0d8SMitch Phillips       p = malloc(size);
66*f7c5c0d8SMitch Phillips       assert(p);
67*f7c5c0d8SMitch Phillips       found = (p == old_p);
68*f7c5c0d8SMitch Phillips       free(p);
69*f7c5c0d8SMitch Phillips     }
70*f7c5c0d8SMitch Phillips     assert(found);
71*f7c5c0d8SMitch Phillips   }
72*f7c5c0d8SMitch Phillips   if (!strcmp(argv[1], "threshold")) {
73*f7c5c0d8SMitch Phillips     // Verifies that a chunk of size greater than the threshold will be freed
74*f7c5c0d8SMitch Phillips     // right away. Alignment has no impact on the threshold.
75*f7c5c0d8SMitch Phillips     allocated_bytes = __sanitizer_get_current_allocated_bytes();
76*f7c5c0d8SMitch Phillips     p = malloc(size + 1);
77*f7c5c0d8SMitch Phillips     assert(p);
78*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
79*f7c5c0d8SMitch Phillips     free(p);
80*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);
81*f7c5c0d8SMitch Phillips     assert(posix_memalign(&p, alignment, size + 1) == 0);
82*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
83*f7c5c0d8SMitch Phillips     free(p);
84*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);
85*f7c5c0d8SMitch Phillips     // Verifies that a chunk of size lower or equal to the threshold will be
86*f7c5c0d8SMitch Phillips     // quarantined.
87*f7c5c0d8SMitch Phillips     p = malloc(size);
88*f7c5c0d8SMitch Phillips     assert(p);
89*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
90*f7c5c0d8SMitch Phillips     free(p);
91*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
92*f7c5c0d8SMitch Phillips     allocated_bytes = __sanitizer_get_current_allocated_bytes();
93*f7c5c0d8SMitch Phillips     assert(posix_memalign(&p, alignment, size) == 0);
94*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
95*f7c5c0d8SMitch Phillips     free(p);
96*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
97*f7c5c0d8SMitch Phillips   }
98*f7c5c0d8SMitch Phillips   if (!strcmp(argv[1], "oldquarantine")) {
99*f7c5c0d8SMitch Phillips     // Verifies that we quarantine everything if the deprecated quarantine
100*f7c5c0d8SMitch Phillips     // option is specified. Alignment has no impact on the threshold.
101*f7c5c0d8SMitch Phillips     allocated_bytes = __sanitizer_get_current_allocated_bytes();
102*f7c5c0d8SMitch Phillips     p = malloc(size);
103*f7c5c0d8SMitch Phillips     assert(p);
104*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
105*f7c5c0d8SMitch Phillips     free(p);
106*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
107*f7c5c0d8SMitch Phillips     allocated_bytes = __sanitizer_get_current_allocated_bytes();
108*f7c5c0d8SMitch Phillips     assert(posix_memalign(&p, alignment, size) == 0);
109*f7c5c0d8SMitch Phillips     assert(p);
110*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
111*f7c5c0d8SMitch Phillips     free(p);
112*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
113*f7c5c0d8SMitch Phillips     // Secondary backed allocation.
114*f7c5c0d8SMitch Phillips     allocated_bytes = __sanitizer_get_current_allocated_bytes();
115*f7c5c0d8SMitch Phillips     p = malloc(1U << 19);
116*f7c5c0d8SMitch Phillips     assert(p);
117*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
118*f7c5c0d8SMitch Phillips     free(p);
119*f7c5c0d8SMitch Phillips     assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
120*f7c5c0d8SMitch Phillips   }
121*f7c5c0d8SMitch Phillips 
122*f7c5c0d8SMitch Phillips   return 0;
123*f7c5c0d8SMitch Phillips }
124