brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 4ddfd42 Raw
148 lines · cpp
1// Test for ASAN_OPTIONS=start_deactivated=1 mode.2// Main executable is uninstrumented, but linked to ASan runtime. The shared3// library is instrumented. Memory errors before dlopen are not detected.4// Fails with debug checks: https://bugs.llvm.org/show_bug.cgi?id=468625// XFAIL: !compiler-rt-optimized6 7// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -std=c++11 -fPIC -shared -o %t-so.so8// RUN: %clangxx -O0 %s -std=c++11 -c -o %t.o9// RUN: %clangxx_asan -O0 %t.o %libdl -o %t10// RUN: %env_asan_opts=start_deactivated=1,allocator_may_return_null=0 \11// RUN:   ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 not %run %t 2>&1 | FileCheck %s12// RUN: %env_asan_opts=start_deactivated=1 \13// RUN:   ASAN_ACTIVATION_OPTIONS=help=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HELP14// RUN: %env_asan_opts=start_deactivated=1,verbosity=1 \15// RUN:   ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED16// RUN: %env_asan_opts=start_deactivated=1 \17// RUN:   ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED-V018 19// Check that verbosity=1 in activation flags affects reporting of unrecognized activation flags.20// RUN: %env_asan_opts=start_deactivated=1 \21// RUN:   ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0,verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED22 23 24// END.25 26#if !defined(SHARED_LIB)27 28#include <assert.h>29#include <dlfcn.h>30#include <stdio.h>31#include <stdlib.h>32#include <string.h>33#include <unistd.h>34 35#include <string>36 37#include "sanitizer/asan_interface.h"38 39void test_malloc_shadow(char *p, size_t sz, bool expect_redzones) {40  // Last byte of the left redzone, if present.41  assert((char *)__asan_region_is_poisoned(p - 1, sz + 1) ==42         (expect_redzones ? p - 1 : nullptr));43  // The user memory.44  assert((char *)__asan_region_is_poisoned(p, sz) == nullptr);45  // First byte of the right redzone, if present.46  assert((char *)__asan_region_is_poisoned(p, sz + 1) ==47         (expect_redzones ? p + sz : nullptr));48}49 50typedef void (*Fn)();51 52int main(int argc, char *argv[]) {53  constexpr unsigned nPtrs = 200;54  char *ptrs[nPtrs];55 56  // Before activation: no redzones.57  for (size_t sz = 1; sz < nPtrs; ++sz) {58    ptrs[sz] = (char *)malloc(sz);59    test_malloc_shadow(ptrs[sz], sz, false);60  }61 62  // Create a honey pot for the future, instrumented, allocations. Since the63  // quarantine is disabled, chunks are going to be recycled right away and64  // reused for the new allocations. New allocations must get the proper65  // redzones anyway, whether it's a fresh or reused allocation.66  constexpr size_t HoneyPotBlockSize = 4096;67  constexpr int HoneyPotSize = 200;68  char *honeyPot[HoneyPotSize];69  for (int i = 1; i < HoneyPotSize; ++i) {70    honeyPot[i] = (char *)malloc(HoneyPotBlockSize);71    test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, false);72  }73  for (int i = 1; i < HoneyPotSize; ++i)74    free(honeyPot[i]);75 76  std::string path = std::string(argv[0]) + "-so.so";77  void *dso = dlopen(path.c_str(), RTLD_NOW);78  if (!dso) {79    fprintf(stderr, "dlopen failed: %s\n", dlerror());80    return 1;81  }82 83  // After this line ASan is activated and starts detecting errors.84  void *fn = dlsym(dso, "do_another_bad_thing");85  if (!fn) {86    fprintf(stderr, "dlsym failed: %s\n", dlerror());87    return 1;88  }89 90  // After activation: redzones.91  for (int i = 1; i < HoneyPotSize; ++i) {92    honeyPot[i] = (char *)malloc(HoneyPotBlockSize);93    test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, true);94  }95  {96    char *p = (char *)malloc(HoneyPotBlockSize);97    test_malloc_shadow(p, HoneyPotBlockSize, true);98    free(p);99  }100  for (int i = 1; i < HoneyPotSize; ++i)101    free(honeyPot[i]);102 103  // Pre-existing allocations got redzones, too.104  for (size_t sz = 1; sz < nPtrs; ++sz) {105    test_malloc_shadow(ptrs[sz], sz, true);106    free(ptrs[sz]);107  }108 109  // Test that ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 has effect.110  void *p = malloc((unsigned long)-2);111  assert(!p);112  // CHECK: WARNING: AddressSanitizer failed to allocate 0xfff{{.*}} bytes113 114  ((Fn)fn)();115  // CHECK: AddressSanitizer: heap-buffer-overflow116  // CHECK: READ of size 1117  // CHECK: {{#0 .* in do_another_bad_thing}}118  // CHECK: is located 5 bytes after 100-byte region119  // CHECK: in do_another_bad_thing120 121  return 0;122}123 124#else  // SHARED_LIB125 126#include <stdio.h>127#include <stdlib.h>128 129extern "C" void do_another_bad_thing() {130  char *volatile p = (char *)malloc(100);131  printf("%hhx\n", p[105]);132}133 134#endif  // SHARED_LIB135 136// help=1 in activation flags lists only flags are are supported at activation137// CHECK-HELP: Available flags for {{.*}}Sanitizer:138// CHECK-HELP-NOT: handle_segv139// CHECK-HELP: max_redzone140// CHECK-HELP-NOT: handle_segv141 142// unsupported activation flags produce a warning ...143// CHECK-UNSUPPORTED: WARNING: found 1 unrecognized144// CHECK-UNSUPPORTED:   handle_segv145 146// ... but not at verbosity=0147// CHECK-UNSUPPORTED-V0-NOT: WARNING: found {{.*}} unrecognized148