brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · 401219a Raw
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