3737#define HAVE_VALLOC 1
3838#endif
3939
40+ extern " C" {
41+ void malloc_enable (void );
42+ void malloc_disable (void );
43+ int malloc_iterate (uintptr_t base, size_t size,
44+ void (*callback)(uintptr_t base, size_t size, void *arg),
45+ void *arg);
46+ void *valloc (size_t size);
47+ void *pvalloc (size_t size);
48+
49+ #ifndef SCUDO_ENABLE_HOOKS_TESTS
50+ #define SCUDO_ENABLE_HOOKS_TESTS 0
51+ #endif
52+
53+ #if (SCUDO_ENABLE_HOOKS_TESTS == 1) && (SCUDO_ENABLE_HOOKS == 0)
54+ #error "Hooks tests should have hooks enabled as well!"
55+ #endif
56+
4057struct AllocContext {
4158 void *Ptr;
4259 size_t Size;
@@ -47,15 +64,7 @@ struct DeallocContext {
4764static AllocContext AC;
4865static DeallocContext DC;
4966
50- extern " C" {
51- void malloc_enable (void );
52- void malloc_disable (void );
53- int malloc_iterate (uintptr_t base, size_t size,
54- void (*callback)(uintptr_t base, size_t size, void *arg),
55- void *arg);
56- void *valloc (size_t size);
57- void *pvalloc (size_t size);
58-
67+ #if (SCUDO_ENABLE_HOOKS_TESTS == 1)
5968__attribute__ ((visibility(" default" ))) void __scudo_allocate_hook(void *Ptr,
6069 size_t Size) {
6170 AC.Ptr = Ptr;
@@ -64,8 +73,35 @@ __attribute__((visibility("default"))) void __scudo_allocate_hook(void *Ptr,
6473__attribute__ ((visibility(" default" ))) void __scudo_deallocate_hook(void *Ptr) {
6574 DC.Ptr = Ptr;
6675}
76+ #endif // (SCUDO_ENABLE_HOOKS_TESTS == 1)
6777}
6878
79+ class ScudoWrappersCTest : public Test {
80+ protected:
81+ void SetUp () override {
82+ if (SCUDO_ENABLE_HOOKS && !SCUDO_ENABLE_HOOKS_TESTS)
83+ printf (" Hooks are enabled but hooks tests are disabled.\n " );
84+ }
85+
86+ void invalidateAllocHookPtrAs (UNUSED void *Ptr) {
87+ if (SCUDO_ENABLE_HOOKS_TESTS)
88+ AC.Ptr = Ptr;
89+ }
90+ void verifyAllocHookPtr (UNUSED void *Ptr) {
91+ if (SCUDO_ENABLE_HOOKS_TESTS)
92+ EXPECT_EQ (Ptr, AC.Ptr );
93+ }
94+ void verifyAllocHookSize (UNUSED size_t Size) {
95+ if (SCUDO_ENABLE_HOOKS_TESTS)
96+ EXPECT_EQ (Size, AC.Size );
97+ }
98+ void verifyDeallocHookPtr (UNUSED void *Ptr) {
99+ if (SCUDO_ENABLE_HOOKS_TESTS)
100+ EXPECT_EQ (Ptr, DC.Ptr );
101+ }
102+ };
103+ using ScudoWrappersCDeathTest = ScudoWrappersCTest;
104+
69105// Note that every C allocation function in the test binary will be fulfilled
70106// by Scudo (this includes the gtest APIs, etc.), which is a test by itself.
71107// But this might also lead to unexpected side-effects, since the allocation and
@@ -78,13 +114,13 @@ __attribute__((visibility("default"))) void __scudo_deallocate_hook(void *Ptr) {
78114
79115static const size_t Size = 100U ;
80116
81- TEST (ScudoWrappersCDeathTest, Malloc) {
117+ TEST_F (ScudoWrappersCDeathTest, Malloc) {
82118 void *P = malloc (Size);
83119 EXPECT_NE (P, nullptr );
84120 EXPECT_LE (Size, malloc_usable_size (P));
85121 EXPECT_EQ (reinterpret_cast <uintptr_t >(P) % FIRST_32_SECOND_64 (8U , 16U ), 0U );
86- EXPECT_EQ (P, AC. Ptr );
87- EXPECT_EQ (Size, AC. Size );
122+ verifyAllocHookPtr (P );
123+ verifyAllocHookSize ( Size);
88124
89125 // An update to this warning in Clang now triggers in this line, but it's ok
90126 // because the check is expecting a bad pointer and should fail.
@@ -99,7 +135,7 @@ TEST(ScudoWrappersCDeathTest, Malloc) {
99135#endif
100136
101137 free (P);
102- EXPECT_EQ (P, DC. Ptr );
138+ verifyDeallocHookPtr (P );
103139 EXPECT_DEATH (free (P), " " );
104140
105141 P = malloc (0U );
@@ -111,16 +147,16 @@ TEST(ScudoWrappersCDeathTest, Malloc) {
111147 EXPECT_EQ (errno, ENOMEM);
112148}
113149
114- TEST (ScudoWrappersCTest, Calloc) {
150+ TEST_F (ScudoWrappersCTest, Calloc) {
115151 void *P = calloc (1U , Size);
116152 EXPECT_NE (P, nullptr );
117153 EXPECT_LE (Size, malloc_usable_size (P));
118- EXPECT_EQ (P, AC. Ptr );
119- EXPECT_EQ (Size, AC. Size );
154+ verifyAllocHookPtr (P );
155+ verifyAllocHookSize ( Size);
120156 for (size_t I = 0 ; I < Size; I++)
121157 EXPECT_EQ ((reinterpret_cast <uint8_t *>(P))[I], 0U );
122158 free (P);
123- EXPECT_EQ (P, DC. Ptr );
159+ verifyDeallocHookPtr (P );
124160
125161 P = calloc (1U , 0U );
126162 EXPECT_NE (P, nullptr );
@@ -141,7 +177,7 @@ TEST(ScudoWrappersCTest, Calloc) {
141177 EXPECT_EQ (errno, ENOMEM);
142178}
143179
144- TEST (ScudoWrappersCTest, SmallAlign) {
180+ TEST_F (ScudoWrappersCTest, SmallAlign) {
145181 // Allocating pointers by the powers of 2 from 1 to 0x10000
146182 // Using powers of 2 due to memalign using powers of 2 and test more sizes
147183 constexpr size_t MaxSize = 0x10000 ;
@@ -162,7 +198,7 @@ TEST(ScudoWrappersCTest, SmallAlign) {
162198 free (ptr);
163199}
164200
165- TEST (ScudoWrappersCTest, Memalign) {
201+ TEST_F (ScudoWrappersCTest, Memalign) {
166202 void *P;
167203 for (size_t I = FIRST_32_SECOND_64 (2U , 3U ); I <= 18U ; I++) {
168204 const size_t Alignment = 1U << I;
@@ -171,20 +207,20 @@ TEST(ScudoWrappersCTest, Memalign) {
171207 EXPECT_NE (P, nullptr );
172208 EXPECT_LE (Size, malloc_usable_size (P));
173209 EXPECT_EQ (reinterpret_cast <uintptr_t >(P) % Alignment, 0U );
174- EXPECT_EQ (P, AC. Ptr );
175- EXPECT_EQ (Size, AC. Size );
210+ verifyAllocHookPtr (P );
211+ verifyAllocHookSize ( Size);
176212 free (P);
177- EXPECT_EQ (P, DC. Ptr );
213+ verifyDeallocHookPtr (P );
178214
179215 P = nullptr ;
180216 EXPECT_EQ (posix_memalign (&P, Alignment, Size), 0 );
181217 EXPECT_NE (P, nullptr );
182218 EXPECT_LE (Size, malloc_usable_size (P));
183219 EXPECT_EQ (reinterpret_cast <uintptr_t >(P) % Alignment, 0U );
184- EXPECT_EQ (P, AC. Ptr );
185- EXPECT_EQ (Size, AC. Size );
220+ verifyAllocHookPtr (P );
221+ verifyAllocHookSize ( Size);
186222 free (P);
187- EXPECT_EQ (P, DC. Ptr );
223+ verifyDeallocHookPtr (P );
188224 }
189225
190226 EXPECT_EQ (memalign (4096U , SIZE_MAX), nullptr );
@@ -196,78 +232,78 @@ TEST(ScudoWrappersCTest, Memalign) {
196232 for (size_t Alignment = 0U ; Alignment <= 128U ; Alignment++) {
197233 P = memalign (Alignment, 1024U );
198234 EXPECT_NE (P, nullptr );
199- EXPECT_EQ (P, AC. Ptr );
200- EXPECT_EQ (Size, AC. Size );
235+ verifyAllocHookPtr (P );
236+ verifyAllocHookSize ( Size);
201237 free (P);
202- EXPECT_EQ (P, DC. Ptr );
238+ verifyDeallocHookPtr (P );
203239 }
204240 }
205241}
206242
207- TEST (ScudoWrappersCTest, AlignedAlloc) {
243+ TEST_F (ScudoWrappersCTest, AlignedAlloc) {
208244 const size_t Alignment = 4096U ;
209245 void *P = aligned_alloc (Alignment, Alignment * 4U );
210246 EXPECT_NE (P, nullptr );
211247 EXPECT_LE (Alignment * 4U , malloc_usable_size (P));
212248 EXPECT_EQ (reinterpret_cast <uintptr_t >(P) % Alignment, 0U );
213- EXPECT_EQ (P, AC. Ptr );
214- EXPECT_EQ (Alignment * 4U , AC. Size );
249+ verifyAllocHookPtr (P );
250+ verifyAllocHookSize (Alignment * 4U );
215251 free (P);
216- EXPECT_EQ (P, DC. Ptr );
252+ verifyDeallocHookPtr (P );
217253
218254 errno = 0 ;
219255 P = aligned_alloc (Alignment, Size);
220256 EXPECT_EQ (P, nullptr );
221257 EXPECT_EQ (errno, EINVAL);
222258}
223259
224- TEST (ScudoWrappersCDeathTest, Realloc) {
260+ TEST_F (ScudoWrappersCDeathTest, Realloc) {
225261 // realloc(nullptr, N) is malloc(N)
226262 void *P = realloc (nullptr , Size);
227263 EXPECT_NE (P, nullptr );
228- EXPECT_EQ (P, AC. Ptr );
229- EXPECT_EQ (Size, AC. Size );
264+ verifyAllocHookPtr (P );
265+ verifyAllocHookSize ( Size);
230266 free (P);
231- EXPECT_EQ (P, DC. Ptr );
267+ verifyDeallocHookPtr (P );
232268
233269 P = malloc (Size);
234270 EXPECT_NE (P, nullptr );
235271 // realloc(P, 0U) is free(P) and returns nullptr
236272 EXPECT_EQ (realloc (P, 0U ), nullptr );
237- EXPECT_EQ (P, DC. Ptr );
273+ verifyDeallocHookPtr (P );
238274
239275 P = malloc (Size);
240276 EXPECT_NE (P, nullptr );
241277 EXPECT_LE (Size, malloc_usable_size (P));
242278 memset (P, 0x42 , Size);
243279
244- AC. Ptr = reinterpret_cast <void *>(0xdeadbeef );
280+ invalidateAllocHookPtrAs ( reinterpret_cast <void *>(0xdeadbeef ) );
245281 void *OldP = P;
246282 P = realloc (P, Size * 2U );
247283 EXPECT_NE (P, nullptr );
248284 EXPECT_LE (Size * 2U , malloc_usable_size (P));
249285 for (size_t I = 0 ; I < Size; I++)
250286 EXPECT_EQ (0x42 , (reinterpret_cast <uint8_t *>(P))[I]);
251287 if (OldP == P) {
252- EXPECT_EQ (AC. Ptr , reinterpret_cast <void *>(0xdeadbeef ));
288+ verifyAllocHookPtr ( reinterpret_cast <void *>(0xdeadbeef ));
253289 } else {
254- EXPECT_EQ (P, AC. Ptr );
255- EXPECT_EQ (Size * 2U , AC. Size );
256- EXPECT_EQ (OldP, DC. Ptr );
290+ verifyAllocHookPtr (P );
291+ verifyAllocHookSize (Size * 2U );
292+ verifyDeallocHookPtr (OldP);
257293 }
258294
259- AC. Ptr = reinterpret_cast <void *>(0xdeadbeef );
295+ invalidateAllocHookPtrAs ( reinterpret_cast <void *>(0xdeadbeef ) );
260296 OldP = P;
261297 P = realloc (P, Size / 2U );
262298 EXPECT_NE (P, nullptr );
263299 EXPECT_LE (Size / 2U , malloc_usable_size (P));
264300 for (size_t I = 0 ; I < Size / 2U ; I++)
265301 EXPECT_EQ (0x42 , (reinterpret_cast <uint8_t *>(P))[I]);
266302 if (OldP == P) {
267- EXPECT_EQ (AC. Ptr , reinterpret_cast <void *>(0xdeadbeef ));
303+ verifyAllocHookPtr ( reinterpret_cast <void *>(0xdeadbeef ));
268304 } else {
269- EXPECT_EQ (P, AC. Ptr );
270- EXPECT_EQ (Size / 2U , AC. Size );
305+ verifyAllocHookPtr (P );
306+ verifyAllocHookSize (Size / 2U );
271307 }
272308 free (P);
273309
@@ -302,7 +338,7 @@ TEST(ScudoWrappersCDeathTest, Realloc) {
302338}
303339
304340#if !SCUDO_FUCHSIA
305- TEST (ScudoWrappersCTest, MallOpt) {
341+ TEST_F (ScudoWrappersCTest, MallOpt) {
306342 errno = 0 ;
307343 EXPECT_EQ (mallopt (-1000 , 1 ), 0 );
308344 // mallopt doesn't set errno.
@@ -323,19 +359,19 @@ TEST(ScudoWrappersCTest, MallOpt) {
323359}
324360#endif
325361
326- TEST (ScudoWrappersCTest, OtherAlloc) {
362+ TEST_F (ScudoWrappersCTest, OtherAlloc) {
327363#if HAVE_PVALLOC
328364 const size_t PageSize = static_cast <size_t >(sysconf (_SC_PAGESIZE));
329365
330366 void *P = pvalloc (Size);
331367 EXPECT_NE (P, nullptr );
332368 EXPECT_EQ (reinterpret_cast <uintptr_t >(P) & (PageSize - 1 ), 0U );
333369 EXPECT_LE (PageSize, malloc_usable_size (P));
334- EXPECT_EQ (P, AC. Ptr );
370+ verifyAllocHookPtr (P );
335371 // Size will be rounded up to PageSize.
336- EXPECT_EQ (PageSize, AC. Size );
372+ verifyAllocHookSize (PageSize);
337373 free (P);
338- EXPECT_EQ (P, DC. Ptr );
374+ verifyDeallocHookPtr (P );
339375
340376 EXPECT_EQ (pvalloc (SIZE_MAX), nullptr );
341377
@@ -351,7 +387,7 @@ TEST(ScudoWrappersCTest, OtherAlloc) {
351387}
352388
353389#if !SCUDO_FUCHSIA
354- TEST (ScudoWrappersCTest, MallInfo) {
390+ TEST_F (ScudoWrappersCTest, MallInfo) {
355391 // mallinfo is deprecated.
356392#pragma clang diagnostic push
357393#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -372,7 +408,7 @@ TEST(ScudoWrappersCTest, MallInfo) {
372408#endif
373409
374410#if __GLIBC_PREREQ(2, 33)
375- TEST (ScudoWrappersCTest, MallInfo2) {
411+ TEST_F (ScudoWrappersCTest, MallInfo2) {
376412 const size_t BypassQuarantineSize = 1024U ;
377413 struct mallinfo2 MI = mallinfo2 ();
378414 size_t Allocated = MI.uordblks ;
@@ -404,7 +440,7 @@ static void callback(uintptr_t Base, UNUSED size_t Size, UNUSED void *Arg) {
404440// To achieve this, we allocate a chunk for which the backing block will be
405441// aligned on a page, then run the malloc_iterate on both the pages that the
406442// block is a boundary for. It must only be seen once by the callback function.
407- TEST (ScudoWrappersCTest, MallocIterateBoundary) {
443+ TEST_F (ScudoWrappersCTest, MallocIterateBoundary) {
408444 const size_t PageSize = static_cast <size_t >(sysconf (_SC_PAGESIZE));
409445#if SCUDO_ANDROID
410446 // Android uses a 16 byte alignment for both 32 bit and 64 bit.
@@ -456,7 +492,7 @@ TEST(ScudoWrappersCTest, MallocIterateBoundary) {
456492
457493// Fuchsia doesn't have alarm, fork or malloc_info.
458494#if !SCUDO_FUCHSIA
459- TEST (ScudoWrappersCDeathTest, MallocDisableDeadlock) {
495+ TEST_F (ScudoWrappersCDeathTest, MallocDisableDeadlock) {
460496 // We expect heap operations within a disable/enable scope to deadlock.
461497 EXPECT_DEATH (
462498 {
@@ -471,7 +507,7 @@ TEST(ScudoWrappersCDeathTest, MallocDisableDeadlock) {
471507 " " );
472508}
473509
474- TEST (ScudoWrappersCTest, MallocInfo) {
510+ TEST_F (ScudoWrappersCTest, MallocInfo) {
475511 // Use volatile so that the allocations don't get optimized away.
476512 void *volatile P1 = malloc (1234 );
477513 void *volatile P2 = malloc (4321 );
@@ -491,7 +527,7 @@ TEST(ScudoWrappersCTest, MallocInfo) {
491527 free (P2);
492528}
493529
494- TEST (ScudoWrappersCDeathTest, Fork) {
530+ TEST_F (ScudoWrappersCDeathTest, Fork) {
495531 void *P;
496532 pid_t Pid = fork ();
497533 EXPECT_GE (Pid, 0 ) << strerror (errno);
@@ -543,7 +579,7 @@ static void *enableMalloc(UNUSED void *Unused) {
543579 return nullptr ;
544580}
545581
546- TEST (ScudoWrappersCTest, DisableForkEnable) {
582+ TEST_F (ScudoWrappersCTest, DisableForkEnable) {
547583 pthread_t ThreadId;
548584 Ready = false ;
549585 EXPECT_EQ (pthread_create (&ThreadId, nullptr , &enableMalloc, nullptr ), 0 );
0 commit comments