348 lines · cpp
1//===-- asan_noinst_test.cpp ----------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of AddressSanitizer, an address sanity checker.10//11// This test file should be compiled w/o asan instrumentation.12//===----------------------------------------------------------------------===//13 14#include <assert.h>15#include <sanitizer/allocator_interface.h>16#include <stdio.h>17#include <stdlib.h>18#include <string.h> // for memset()19 20#include <algorithm>21#include <limits>22#include <vector>23 24#include "asan_allocator.h"25#include "asan_internal.h"26#include "asan_mapping.h"27#include "asan_test_utils.h"28 29using namespace __sanitizer;30 31// ATTENTION!32// Please don't call intercepted functions (including malloc() and friends)33// in this test. The static runtime library is linked explicitly (without34// -fsanitize=address), thus the interceptors do not work correctly on OS X.35 36// Make sure __asan_init is called before any test case is run.37struct AsanInitCaller {38 AsanInitCaller() {39 __asan_init();40 }41};42static AsanInitCaller asan_init_caller;43 44TEST(AddressSanitizer, InternalSimpleDeathTest) {45 EXPECT_DEATH(exit(1), "");46}47 48static void *MallocStress(void *NumOfItrPtr) {49 size_t n = *((size_t *)NumOfItrPtr);50 u32 seed = my_rand();51 BufferedStackTrace stack1;52 stack1.trace_buffer[0] = 0xa123;53 stack1.trace_buffer[1] = 0xa456;54 stack1.size = 2;55 56 BufferedStackTrace stack2;57 stack2.trace_buffer[0] = 0xb123;58 stack2.trace_buffer[1] = 0xb456;59 stack2.size = 2;60 61 BufferedStackTrace stack3;62 stack3.trace_buffer[0] = 0xc123;63 stack3.trace_buffer[1] = 0xc456;64 stack3.size = 2;65 66 std::vector<void *> vec;67 for (size_t i = 0; i < n; i++) {68 if ((i % 3) == 0) {69 if (vec.empty()) continue;70 size_t idx = my_rand_r(&seed) % vec.size();71 void *ptr = vec[idx];72 vec[idx] = vec.back();73 vec.pop_back();74 __asan::asan_free(ptr, &stack1);75 } else {76 size_t size = my_rand_r(&seed) % 1000 + 1;77 switch ((my_rand_r(&seed) % 128)) {78 case 0: size += 1024; break;79 case 1: size += 2048; break;80 case 2: size += 4096; break;81 }82 size_t alignment = 1 << (my_rand_r(&seed) % 10 + 1);83 char *ptr = (char *)__asan::asan_memalign(alignment, size, &stack2);84 EXPECT_EQ(size, __asan::asan_malloc_usable_size(ptr, 0, 0));85 vec.push_back(ptr);86 ptr[0] = 0;87 ptr[size-1] = 0;88 ptr[size/2] = 0;89 }90 }91 for (size_t i = 0; i < vec.size(); i++) __asan::asan_free(vec[i], &stack3);92 return nullptr;93}94 95TEST(AddressSanitizer, NoInstMallocTest) {96 const size_t kNumIterations = (ASAN_LOW_MEMORY) ? 300000 : 1000000;97 MallocStress((void *)&kNumIterations);98}99 100TEST(AddressSanitizer, ThreadedMallocStressTest) {101 const int kNumThreads = 4;102 const size_t kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;103 pthread_t t[kNumThreads];104 for (int i = 0; i < kNumThreads; i++) {105 PTHREAD_CREATE(&t[i], 0, (void *(*)(void *x))MallocStress,106 (void *)&kNumIterations);107 }108 for (int i = 0; i < kNumThreads; i++) {109 PTHREAD_JOIN(t[i], 0);110 }111}112 113static void PrintShadow(const char *tag, uptr ptr, size_t size) {114 fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size);115 uptr prev_shadow = 0;116 for (sptr i = -32; i < (sptr)size + 32; i++) {117 uptr shadow = __asan::MemToShadow(ptr + i);118 if (i == 0 || i == (sptr)size)119 fprintf(stderr, ".");120 if (shadow != prev_shadow) {121 prev_shadow = shadow;122 fprintf(stderr, "%02x", (int)*(u8*)shadow);123 }124 }125 fprintf(stderr, "\n");126}127 128TEST(AddressSanitizer, DISABLED_InternalPrintShadow) {129 for (size_t size = 1; size <= 513; size++) {130 char *ptr = new char[size];131 PrintShadow("m", (uptr)ptr, size);132 delete [] ptr;133 PrintShadow("f", (uptr)ptr, size);134 }135}136 137TEST(AddressSanitizer, QuarantineTest) {138 UNINITIALIZED BufferedStackTrace stack;139 stack.trace_buffer[0] = 0x890;140 stack.size = 1;141 142 const int size = 1024;143 void *p = __asan::asan_malloc(size, &stack);144 __asan::asan_free(p, &stack);145 size_t i;146 size_t max_i = 1 << 30;147 for (i = 0; i < max_i; i++) {148 void *p1 = __asan::asan_malloc(size, &stack);149 __asan::asan_free(p1, &stack);150 if (p1 == p) break;151 }152 EXPECT_GE(i, 10000U);153 EXPECT_LT(i, max_i);154}155 156#if !defined(__NetBSD__)157void *ThreadedQuarantineTestWorker(void *unused) {158 (void)unused;159 u32 seed = my_rand();160 UNINITIALIZED BufferedStackTrace stack;161 stack.trace_buffer[0] = 0x890;162 stack.size = 1;163 164 for (size_t i = 0; i < 1000; i++) {165 void *p = __asan::asan_malloc(1 + (my_rand_r(&seed) % 4000), &stack);166 __asan::asan_free(p, &stack);167 }168 return NULL;169}170 171// Check that the thread local allocators are flushed when threads are172// destroyed.173TEST(AddressSanitizer, ThreadedQuarantineTest) {174 // Run the routine once to warm up ASAN internal structures to get more175 // predictable incremental memory changes.176 pthread_t t;177 PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);178 PTHREAD_JOIN(t, 0);179 180 const int n_threads = 3000;181 size_t mmaped1 = __sanitizer_get_heap_size();182 for (int i = 0; i < n_threads; i++) {183 pthread_t t;184 PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);185 PTHREAD_JOIN(t, 0);186 size_t mmaped2 = __sanitizer_get_heap_size();187 // Figure out why this much memory is required.188 EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));189 }190}191#endif192 193void *ThreadedOneSizeMallocStress(void *unused) {194 (void)unused;195 UNINITIALIZED BufferedStackTrace stack;196 stack.trace_buffer[0] = 0x890;197 stack.size = 1;198 const size_t kNumMallocs = 1000;199 for (int iter = 0; iter < 1000; iter++) {200 void *p[kNumMallocs];201 for (size_t i = 0; i < kNumMallocs; i++) {202 p[i] = __asan::asan_malloc(32, &stack);203 }204 for (size_t i = 0; i < kNumMallocs; i++) {205 __asan::asan_free(p[i], &stack);206 }207 }208 return NULL;209}210 211TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {212 const int kNumThreads = 4;213 pthread_t t[kNumThreads];214 for (int i = 0; i < kNumThreads; i++) {215 PTHREAD_CREATE(&t[i], 0, ThreadedOneSizeMallocStress, 0);216 }217 for (int i = 0; i < kNumThreads; i++) {218 PTHREAD_JOIN(t[i], 0);219 }220}221 222TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {223 using __asan::kHighMemEnd;224 // Check that __asan_region_is_poisoned works for shadow regions.225 uptr ptr = kLowShadowBeg + 200;226 EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));227 ptr = kShadowGapBeg + 200;228 EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));229 ptr = kHighShadowBeg + 200;230 EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));231}232 233// Test __asan_load1 & friends.234typedef void (*CB)(uptr p);235static void TestLoadStoreCallbacks(CB cb[2][5]) {236 uptr buggy_ptr;237 238 __asan_test_only_reported_buggy_pointer = &buggy_ptr;239 UNINITIALIZED BufferedStackTrace stack;240 stack.trace_buffer[0] = 0x890;241 stack.size = 1;242 243 for (uptr len = 16; len <= 32; len++) {244 char *ptr = (char*) __asan::asan_malloc(len, &stack);245 uptr p = reinterpret_cast<uptr>(ptr);246 for (uptr is_write = 0; is_write <= 1; is_write++) {247 for (uptr size_log = 0; size_log <= 4; size_log++) {248 uptr size = 1 << size_log;249 CB call = cb[is_write][size_log];250 // Iterate only size-aligned offsets.251 for (uptr offset = 0; offset <= len; offset += size) {252 buggy_ptr = 0;253 call(p + offset);254 if (offset + size <= len)255 EXPECT_EQ(buggy_ptr, 0U);256 else257 EXPECT_EQ(buggy_ptr, p + offset);258 }259 }260 }261 __asan::asan_free(ptr, &stack);262 }263 __asan_test_only_reported_buggy_pointer = 0;264}265 266TEST(AddressSanitizer, LoadStoreCallbacks) {267 CB cb[2][5] = {{268 __asan_load1,269 __asan_load2,270 __asan_load4,271 __asan_load8,272 __asan_load16,273 },274 {275 __asan_store1,276 __asan_store2,277 __asan_store4,278 __asan_store8,279 __asan_store16,280 }};281 TestLoadStoreCallbacks(cb);282}283 284#if defined(__x86_64__) && \285 !(defined(SANITIZER_APPLE) || defined(SANITIZER_WINDOWS))286// clang-format off287 288#define CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(s, reg, op) \289 void CallAsanMemoryAccessAdd##reg##op##s(uptr address) { \290 asm("push %%" #reg " \n" \291 "mov %[x], %%" #reg " \n" \292 "call __asan_check_" #op "_add_" #s "_" #reg "\n" \293 "pop %%" #reg " \n" \294 : \295 : [x] "r"(address) \296 : "r8", "rdi"); \297 }298 299#define TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(reg) \300 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(1, reg, load) \301 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(1, reg, store) \302 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(2, reg, load) \303 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(2, reg, store) \304 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(4, reg, load) \305 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(4, reg, store) \306 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(8, reg, load) \307 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(8, reg, store) \308 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(16, reg, load) \309 CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(16, reg, store) \310 \311 TEST(AddressSanitizer, LoadStoreCallbacksAddX86##reg) { \312 CB cb[2][5] = {{ \313 CallAsanMemoryAccessAdd##reg##load1, \314 CallAsanMemoryAccessAdd##reg##load2, \315 CallAsanMemoryAccessAdd##reg##load4, \316 CallAsanMemoryAccessAdd##reg##load8, \317 CallAsanMemoryAccessAdd##reg##load16, \318 }, \319 { \320 CallAsanMemoryAccessAdd##reg##store1, \321 CallAsanMemoryAccessAdd##reg##store2, \322 CallAsanMemoryAccessAdd##reg##store4, \323 CallAsanMemoryAccessAdd##reg##store8, \324 CallAsanMemoryAccessAdd##reg##store16, \325 }}; \326 TestLoadStoreCallbacks(cb); \327 }328 329// Instantiate all but R10 and R11 callbacks. We are using PLTSafe class with330// the intrinsic, which guarantees that the code generation will never emit331// R10 or R11 callbacks.332TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RAX)333TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBX)334TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RCX)335TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDX)336TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RSI)337TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDI)338TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBP)339TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R8)340TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R9)341TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R12)342TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R13)343TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R14)344TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R15)345 346// clang-format on347#endif348