brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · e14d946 Raw
121 lines · cpp
1// Test to demonstrate compile-time disabling of container-overflow checks2// in order to handle uninstrumented libraries3// UNSUPPORTED: target={{.*windows-.*}}4 5// Mimic a closed-source library compiled without ASan6// RUN: %clangxx_asan -fno-sanitize=address -DSHARED_LIB %s %fPIC -shared -o %t-so.so7 8// Mimic multiple files being linked into a single executable,9// %t-object.o and %t-main compiled seperately and then linked together10// RUN: %clangxx_asan -DMULTI_SOURCE %s -c -o %t-object.o11// RUN: %clangxx_asan %s -c -o %t-main.o12// RUN: %clangxx_asan -o %t %t-main.o %t-object.o %libdl13// RUN: not %run %t 2>&1 | FileCheck %s14 15// Disable container overflow checks at runtime using ASAN_OPTIONS=detect_container_overflow=016// RUN: %env_asan_opts=detect_container_overflow=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-NO-CONTAINER-OVERFLOW %s17 18// RUN: %clangxx_asan -D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__ -DMULTI_SOURCE %s -c -o %t-object.o19// RUN: %clangxx_asan -D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__ %s -c -o %t-main.o20// RUN: %clangxx_asan -D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__ -o %t %t-main.o %t-object.o %libdl21// RUN: %run %t 2>&1 | FileCheck --check-prefix=CHECK-NO-CONTAINER-OVERFLOW %s22//23// UNSUPPORTED: true24 25#include <assert.h>26#include <sanitizer/common_interface_defs.h>27#include <stdio.h>28 29template <typename T> class Stack {30private:31  T data[5];32  size_t size;33 34public:35  Stack() : size(0) {36#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__37    // Mark entire storage as unaddressable initially38    __sanitizer_annotate_contiguous_container(data, data + 5, data + 5, data);39#endif40  }41 42  ~Stack() {43#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__44    __sanitizer_annotate_contiguous_container(data, data + 5, data + size,45                                              data + 5);46#endif47  }48 49  void push(const T &value) {50    assert(size < 5 && "Stack overflow");51#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__52    __sanitizer_annotate_contiguous_container(data, data + 5, data + size,53                                              data + size + 1);54#endif55    data[size++] = value;56  }57 58  T pop() {59    assert(size > 0 && "Cannot pop from empty stack");60    T result = data[--size];61#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__62    __sanitizer_annotate_contiguous_container(data, data + 5, data + size + 1,63                                              data + size);64#endif65    return result;66  }67};68 69#ifdef SHARED_LIB70// Mimics a closed-source library compiled without ASan71 72extern "C" void push_value_to_stack(Stack<int> &stack) { stack.push(42); }73#else // SHARED_LIB74 75#  include <dlfcn.h>76#  include <string>77 78typedef void (*push_func_t)(Stack<int> &);79 80#  if defined(MULTI_SOURCE)81extern push_func_t push_value;82 83extern "C" void do_push_value_to_stack(Stack<int> &stack) {84  assert(push_value);85  push_value(stack);86}87 88#  else89push_func_t push_value = nullptr;90 91extern "C" void do_push_value_to_stack(Stack<int> &stack);92 93int main(int argc, char *argv[]) {94  std::string path = std::string(argv[0]) + "-so.so";95  printf("Loading library: %s\n", path.c_str());96 97  void *lib = dlopen(path.c_str(), RTLD_NOW);98  assert(lib);99 100  push_value = (push_func_t)dlsym(lib, "push_value_to_stack");101  assert(push_value);102 103  Stack<int> stack;104  do_push_value_to_stack(stack);105 106  // BOOM! uninstrumented library didn't update container bounds107  int value = stack.pop();108  // CHECK: AddressSanitizer: container-overflow109  printf("Popped value: %d\n", value);110  assert(value == 42 && "Expected value 42");111 112  dlclose(lib);113  printf("SUCCESS\n");114  // CHECK-NO-CONTAINER-OVERFLOW: SUCCESS115  return 0;116}117 118#  endif // MULTI_SOURCE119 120#endif // SHARED_LIB121