• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- asan_interface_test.cc --------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of AddressSanitizer, an address sanity checker.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "asan_test_utils.h"
14 #include <sanitizer/allocator_interface.h>
15 #include <sanitizer/asan_interface.h>
16 
TEST(AddressSanitizerInterface,GetEstimatedAllocatedSize)17 TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
18   EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
19   const size_t sizes[] = { 1, 30, 1<<30 };
20   for (size_t i = 0; i < 3; i++) {
21     EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
22   }
23 }
24 
25 static const char* kGetAllocatedSizeErrorMsg =
26   "attempting to call __sanitizer_get_allocated_size";
27 
TEST(AddressSanitizerInterface,GetAllocatedSizeAndOwnershipTest)28 TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
29   const size_t kArraySize = 100;
30   char *array = Ident((char*)malloc(kArraySize));
31   int *int_ptr = Ident(new int);
32 
33   // Allocated memory is owned by allocator. Allocated size should be
34   // equal to requested size.
35   EXPECT_EQ(true, __sanitizer_get_ownership(array));
36   EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
37   EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
38   EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
39 
40   // We cannot call GetAllocatedSize from the memory we didn't map,
41   // and from the interior pointers (not returned by previous malloc).
42   void *wild_addr = (void*)0x1;
43   EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
44   EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
45                kGetAllocatedSizeErrorMsg);
46   EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
47   EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
48                kGetAllocatedSizeErrorMsg);
49 
50   // NULL is not owned, but is a valid argument for
51   // __sanitizer_get_allocated_size().
52   EXPECT_FALSE(__sanitizer_get_ownership(NULL));
53   EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
54 
55   // When memory is freed, it's not owned, and call to GetAllocatedSize
56   // is forbidden.
57   free(array);
58   EXPECT_FALSE(__sanitizer_get_ownership(array));
59   EXPECT_DEATH(__sanitizer_get_allocated_size(array),
60                kGetAllocatedSizeErrorMsg);
61   delete int_ptr;
62 
63   void *zero_alloc = Ident(malloc(0));
64   if (zero_alloc != 0) {
65     // If malloc(0) is not null, this pointer is owned and should have valid
66     // allocated size.
67     EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
68     // Allocated size is 0 or 1 depending on the allocator used.
69     EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
70   }
71   free(zero_alloc);
72 }
73 
TEST(AddressSanitizerInterface,GetCurrentAllocatedBytesTest)74 TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
75   size_t before_malloc, after_malloc, after_free;
76   char *array;
77   const size_t kMallocSize = 100;
78   before_malloc = __sanitizer_get_current_allocated_bytes();
79 
80   array = Ident((char*)malloc(kMallocSize));
81   after_malloc = __sanitizer_get_current_allocated_bytes();
82   EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
83 
84   free(array);
85   after_free = __sanitizer_get_current_allocated_bytes();
86   EXPECT_EQ(before_malloc, after_free);
87 }
88 
TEST(AddressSanitizerInterface,GetHeapSizeTest)89 TEST(AddressSanitizerInterface, GetHeapSizeTest) {
90   // ASan allocator does not keep huge chunks in free list, but unmaps them.
91   // The chunk should be greater than the quarantine size,
92   // otherwise it will be stuck in quarantine instead of being unmaped.
93   static const size_t kLargeMallocSize = (1 << 28) + 1;  // 256M
94   free(Ident(malloc(kLargeMallocSize)));  // Drain quarantine.
95   size_t old_heap_size = __sanitizer_get_heap_size();
96   for (int i = 0; i < 3; i++) {
97     // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
98     free(Ident(malloc(kLargeMallocSize)));
99     EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
100   }
101 }
102 
103 static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
104 static const size_t kManyThreadsIterations = 250;
105 static const size_t kManyThreadsNumThreads =
106   (SANITIZER_WORDSIZE == 32) ? 40 : 200;
107 
ManyThreadsWithStatsWorker(void * arg)108 static void *ManyThreadsWithStatsWorker(void *arg) {
109   (void)arg;
110   for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
111     for (size_t size_index = 0; size_index < 4; size_index++) {
112       free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
113     }
114   }
115   // Just one large allocation.
116   free(Ident(malloc(1 << 20)));
117   return 0;
118 }
119 
TEST(AddressSanitizerInterface,ManyThreadsWithStatsStressTest)120 TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
121   size_t before_test, after_test, i;
122   pthread_t threads[kManyThreadsNumThreads];
123   before_test = __sanitizer_get_current_allocated_bytes();
124   for (i = 0; i < kManyThreadsNumThreads; i++) {
125     PTHREAD_CREATE(&threads[i], 0,
126                    (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
127   }
128   for (i = 0; i < kManyThreadsNumThreads; i++) {
129     PTHREAD_JOIN(threads[i], 0);
130   }
131   after_test = __sanitizer_get_current_allocated_bytes();
132   // ASan stats also reflect memory usage of internal ASan RTL structs,
133   // so we can't check for equality here.
134   EXPECT_LT(after_test, before_test + (1UL<<20));
135 }
136 
DoDoubleFree()137 static void DoDoubleFree() {
138   int *x = Ident(new int);
139   delete Ident(x);
140   delete Ident(x);
141 }
142 
MyDeathCallback()143 static void MyDeathCallback() {
144   fprintf(stderr, "MyDeathCallback\n");
145   fflush(0);  // On Windows, stderr doesn't flush on crash.
146 }
147 
TEST(AddressSanitizerInterface,DeathCallbackTest)148 TEST(AddressSanitizerInterface, DeathCallbackTest) {
149   __asan_set_death_callback(MyDeathCallback);
150   EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
151   __asan_set_death_callback(NULL);
152 }
153 
154 static const char* kUseAfterPoisonErrorMessage = "use-after-poison";
155 
156 #define GOOD_ACCESS(ptr, offset)  \
157     EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))
158 
159 #define BAD_ACCESS(ptr, offset) \
160     EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))
161 
TEST(AddressSanitizerInterface,SimplePoisonMemoryRegionTest)162 TEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
163   char *array = Ident((char*)malloc(120));
164   // poison array[40..80)
165   __asan_poison_memory_region(array + 40, 40);
166   GOOD_ACCESS(array, 39);
167   GOOD_ACCESS(array, 80);
168   BAD_ACCESS(array, 40);
169   BAD_ACCESS(array, 60);
170   BAD_ACCESS(array, 79);
171   char value;
172   EXPECT_DEATH(value = Ident(array[40]), kUseAfterPoisonErrorMessage);
173   __asan_unpoison_memory_region(array + 40, 40);
174   // access previously poisoned memory.
175   GOOD_ACCESS(array, 40);
176   GOOD_ACCESS(array, 79);
177   free(array);
178 }
179 
TEST(AddressSanitizerInterface,OverlappingPoisonMemoryRegionTest)180 TEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
181   char *array = Ident((char*)malloc(120));
182   // Poison [0..40) and [80..120)
183   __asan_poison_memory_region(array, 40);
184   __asan_poison_memory_region(array + 80, 40);
185   BAD_ACCESS(array, 20);
186   GOOD_ACCESS(array, 60);
187   BAD_ACCESS(array, 100);
188   // Poison whole array - [0..120)
189   __asan_poison_memory_region(array, 120);
190   BAD_ACCESS(array, 60);
191   // Unpoison [24..96)
192   __asan_unpoison_memory_region(array + 24, 72);
193   BAD_ACCESS(array, 23);
194   GOOD_ACCESS(array, 24);
195   GOOD_ACCESS(array, 60);
196   GOOD_ACCESS(array, 95);
197   BAD_ACCESS(array, 96);
198   free(array);
199 }
200 
TEST(AddressSanitizerInterface,PushAndPopWithPoisoningTest)201 TEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
202   // Vector of capacity 20
203   char *vec = Ident((char*)malloc(20));
204   __asan_poison_memory_region(vec, 20);
205   for (size_t i = 0; i < 7; i++) {
206     // Simulate push_back.
207     __asan_unpoison_memory_region(vec + i, 1);
208     GOOD_ACCESS(vec, i);
209     BAD_ACCESS(vec, i + 1);
210   }
211   for (size_t i = 7; i > 0; i--) {
212     // Simulate pop_back.
213     __asan_poison_memory_region(vec + i - 1, 1);
214     BAD_ACCESS(vec, i - 1);
215     if (i > 1) GOOD_ACCESS(vec, i - 2);
216   }
217   free(vec);
218 }
219 
220 // Make sure that each aligned block of size "2^granularity" doesn't have
221 // "true" value before "false" value.
MakeShadowValid(bool * shadow,int length,int granularity)222 static void MakeShadowValid(bool *shadow, int length, int granularity) {
223   bool can_be_poisoned = true;
224   for (int i = length - 1; i >= 0; i--) {
225     if (!shadow[i])
226       can_be_poisoned = false;
227     if (!can_be_poisoned)
228       shadow[i] = false;
229     if (i % (1 << granularity) == 0) {
230       can_be_poisoned = true;
231     }
232   }
233 }
234 
TEST(AddressSanitizerInterface,PoisoningStressTest)235 TEST(AddressSanitizerInterface, PoisoningStressTest) {
236   const size_t kSize = 24;
237   bool expected[kSize];
238   char *arr = Ident((char*)malloc(kSize));
239   for (size_t l1 = 0; l1 < kSize; l1++) {
240     for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
241       for (size_t l2 = 0; l2 < kSize; l2++) {
242         for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
243           // Poison [l1, l1+s1), [l2, l2+s2) and check result.
244           __asan_unpoison_memory_region(arr, kSize);
245           __asan_poison_memory_region(arr + l1, s1);
246           __asan_poison_memory_region(arr + l2, s2);
247           memset(expected, false, kSize);
248           memset(expected + l1, true, s1);
249           MakeShadowValid(expected, kSize, /*granularity*/ 3);
250           memset(expected + l2, true, s2);
251           MakeShadowValid(expected, kSize, /*granularity*/ 3);
252           for (size_t i = 0; i < kSize; i++) {
253             ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
254           }
255           // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
256           __asan_poison_memory_region(arr, kSize);
257           __asan_unpoison_memory_region(arr + l1, s1);
258           __asan_unpoison_memory_region(arr + l2, s2);
259           memset(expected, true, kSize);
260           memset(expected + l1, false, s1);
261           MakeShadowValid(expected, kSize, /*granularity*/ 3);
262           memset(expected + l2, false, s2);
263           MakeShadowValid(expected, kSize, /*granularity*/ 3);
264           for (size_t i = 0; i < kSize; i++) {
265             ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
266           }
267         }
268       }
269     }
270   }
271   free(arr);
272 }
273 
TEST(AddressSanitizerInterface,GlobalRedzones)274 TEST(AddressSanitizerInterface, GlobalRedzones) {
275   GOOD_ACCESS(glob1, 1 - 1);
276   GOOD_ACCESS(glob2, 2 - 1);
277   GOOD_ACCESS(glob3, 3 - 1);
278   GOOD_ACCESS(glob4, 4 - 1);
279   GOOD_ACCESS(glob5, 5 - 1);
280   GOOD_ACCESS(glob6, 6 - 1);
281   GOOD_ACCESS(glob7, 7 - 1);
282   GOOD_ACCESS(glob8, 8 - 1);
283   GOOD_ACCESS(glob9, 9 - 1);
284   GOOD_ACCESS(glob10, 10 - 1);
285   GOOD_ACCESS(glob11, 11 - 1);
286   GOOD_ACCESS(glob12, 12 - 1);
287   GOOD_ACCESS(glob13, 13 - 1);
288   GOOD_ACCESS(glob14, 14 - 1);
289   GOOD_ACCESS(glob15, 15 - 1);
290   GOOD_ACCESS(glob16, 16 - 1);
291   GOOD_ACCESS(glob17, 17 - 1);
292   GOOD_ACCESS(glob1000, 1000 - 1);
293   GOOD_ACCESS(glob10000, 10000 - 1);
294   GOOD_ACCESS(glob100000, 100000 - 1);
295 
296   BAD_ACCESS(glob1, 1);
297   BAD_ACCESS(glob2, 2);
298   BAD_ACCESS(glob3, 3);
299   BAD_ACCESS(glob4, 4);
300   BAD_ACCESS(glob5, 5);
301   BAD_ACCESS(glob6, 6);
302   BAD_ACCESS(glob7, 7);
303   BAD_ACCESS(glob8, 8);
304   BAD_ACCESS(glob9, 9);
305   BAD_ACCESS(glob10, 10);
306   BAD_ACCESS(glob11, 11);
307   BAD_ACCESS(glob12, 12);
308   BAD_ACCESS(glob13, 13);
309   BAD_ACCESS(glob14, 14);
310   BAD_ACCESS(glob15, 15);
311   BAD_ACCESS(glob16, 16);
312   BAD_ACCESS(glob17, 17);
313   BAD_ACCESS(glob1000, 1000);
314   BAD_ACCESS(glob1000, 1100);  // Redzone is at least 101 bytes.
315   BAD_ACCESS(glob10000, 10000);
316   BAD_ACCESS(glob10000, 11000);  // Redzone is at least 1001 bytes.
317   BAD_ACCESS(glob100000, 100000);
318   BAD_ACCESS(glob100000, 110000);  // Redzone is at least 10001 bytes.
319 }
320 
TEST(AddressSanitizerInterface,PoisonedRegion)321 TEST(AddressSanitizerInterface, PoisonedRegion) {
322   size_t rz = 16;
323   for (size_t size = 1; size <= 64; size++) {
324     char *p = new char[size];
325     for (size_t beg = 0; beg < size + rz; beg++) {
326       for (size_t end = beg; end < size + rz; end++) {
327         void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);
328         if (beg == end) {
329           EXPECT_FALSE(first_poisoned);
330         } else if (beg < size && end <= size) {
331           EXPECT_FALSE(first_poisoned);
332         } else if (beg >= size) {
333           EXPECT_EQ(p + beg, first_poisoned);
334         } else {
335           EXPECT_GT(end, size);
336           EXPECT_EQ(p + size, first_poisoned);
337         }
338       }
339     }
340     delete [] p;
341   }
342 }
343 
344 // This is a performance benchmark for manual runs.
345 // asan's memset interceptor calls mem_is_zero for the entire shadow region.
346 // the profile should look like this:
347 //     89.10%   [.] __memset_sse2
348 //     10.50%   [.] __sanitizer::mem_is_zero
349 // I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
350 // than memset itself.
TEST(AddressSanitizerInterface,DISABLED_StressLargeMemset)351 TEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
352   size_t size = 1 << 20;
353   char *x = new char[size];
354   for (int i = 0; i < 100000; i++)
355     Ident(memset)(x, 0, size);
356   delete [] x;
357 }
358 
359 // Same here, but we run memset with small sizes.
TEST(AddressSanitizerInterface,DISABLED_StressSmallMemset)360 TEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
361   size_t size = 32;
362   char *x = new char[size];
363   for (int i = 0; i < 100000000; i++)
364     Ident(memset)(x, 0, size);
365   delete [] x;
366 }
367 static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
368 static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
369 
TEST(AddressSanitizerInterface,DISABLED_InvalidPoisonAndUnpoisonCallsTest)370 TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
371   char *array = Ident((char*)malloc(120));
372   __asan_unpoison_memory_region(array, 120);
373   // Try to unpoison not owned memory
374   EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
375                kInvalidUnpoisonMessage);
376   EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
377                kInvalidUnpoisonMessage);
378 
379   __asan_poison_memory_region(array, 120);
380   // Try to poison not owned memory.
381   EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
382   EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
383                kInvalidPoisonMessage);
384   free(array);
385 }
386 
387 #if !defined(_WIN32)  // FIXME: This should really be a lit test.
ErrorReportCallbackOneToZ(const char * report)388 static void ErrorReportCallbackOneToZ(const char *report) {
389   int report_len = strlen(report);
390   ASSERT_EQ(6, write(2, "ABCDEF", 6));
391   ASSERT_EQ(report_len, write(2, report, report_len));
392   ASSERT_EQ(6, write(2, "ABCDEF", 6));
393   _exit(1);
394 }
395 
TEST(AddressSanitizerInterface,SetErrorReportCallbackTest)396 TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
397   __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
398   EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),
399                ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
400   __asan_set_error_report_callback(NULL);
401 }
402 #endif
403 
TEST(AddressSanitizerInterface,GetOwnershipStressTest)404 TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
405   std::vector<char *> pointers;
406   std::vector<size_t> sizes;
407   const size_t kNumMallocs = 1 << 9;
408   for (size_t i = 0; i < kNumMallocs; i++) {
409     size_t size = i * 100 + 1;
410     pointers.push_back((char*)malloc(size));
411     sizes.push_back(size);
412   }
413   for (size_t i = 0; i < 4000000; i++) {
414     EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
415     EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
416     size_t idx = i % kNumMallocs;
417     EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
418     EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
419   }
420   for (size_t i = 0, n = pointers.size(); i < n; i++)
421     free(pointers[i]);
422 }
423 
424