105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//===-- asan_interface_test.cc --------------------------------------------===//
205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//
305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//                     The LLVM Compiler Infrastructure
405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//
505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// This file is distributed under the University of Illinois Open Source
605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// License. See LICENSE.TXT for details.
705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//
805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//===----------------------------------------------------------------------===//
905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//
1005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// This file is a part of AddressSanitizer, an address sanity checker.
1105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//
1205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//===----------------------------------------------------------------------===//
1305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov#include "asan_test_utils.h"
146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include <sanitizer/allocator_interface.h>
156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include <sanitizer/asan_interface.h>
1605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
1705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
1905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  const size_t sizes[] = { 1, 30, 1<<30 };
2005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t i = 0; i < 3; i++) {
216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
2205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
2305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
2405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
2505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const char* kGetAllocatedSizeErrorMsg =
266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  "attempting to call __sanitizer_get_allocated_size";
2705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
2805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
2905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  const size_t kArraySize = 100;
3005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *array = Ident((char*)malloc(kArraySize));
3105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  int *int_ptr = Ident(new int);
3205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
3305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Allocated memory is owned by allocator. Allocated size should be
3405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // equal to requested size.
356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_EQ(true, __sanitizer_get_ownership(array));
366a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
386a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
3905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
4005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // We cannot call GetAllocatedSize from the memory we didn't map,
4105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // and from the interior pointers (not returned by previous malloc).
4205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  void *wild_addr = (void*)0x1;
436a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines               kGetAllocatedSizeErrorMsg);
466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
4805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov               kGetAllocatedSizeErrorMsg);
4905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // NULL is not owned, but is a valid argument for
516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  // __sanitizer_get_allocated_size().
526a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_FALSE(__sanitizer_get_ownership(NULL));
536a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
5405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
5505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // When memory is freed, it's not owned, and call to GetAllocatedSize
5605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // is forbidden.
5705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(array);
586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_FALSE(__sanitizer_get_ownership(array));
596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  EXPECT_DEATH(__sanitizer_get_allocated_size(array),
606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines               kGetAllocatedSizeErrorMsg);
6105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  delete int_ptr;
6205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
6305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  void *zero_alloc = Ident(malloc(0));
6405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  if (zero_alloc != 0) {
6505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    // If malloc(0) is not null, this pointer is owned and should have valid
6605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    // allocated size.
676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
6805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    // Allocated size is 0 or 1 depending on the allocator used.
696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
7005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
7105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(zero_alloc);
7205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
7305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
7405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
7505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  size_t before_malloc, after_malloc, after_free;
7605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *array;
7705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  const size_t kMallocSize = 100;
786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  before_malloc = __sanitizer_get_current_allocated_bytes();
7905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
8005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  array = Ident((char*)malloc(kMallocSize));
816a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  after_malloc = __sanitizer_get_current_allocated_bytes();
8205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
8305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
8405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(array);
856a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  after_free = __sanitizer_get_current_allocated_bytes();
8605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EQ(before_malloc, after_free);
8705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
8805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
8905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, GetHeapSizeTest) {
9086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // ASan allocator does not keep huge chunks in free list, but unmaps them.
9105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // The chunk should be greater than the quarantine size,
9205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // otherwise it will be stuck in quarantine instead of being unmaped.
9305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  static const size_t kLargeMallocSize = (1 << 28) + 1;  // 256M
9405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(Ident(malloc(kLargeMallocSize)));  // Drain quarantine.
956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  size_t old_heap_size = __sanitizer_get_heap_size();
9605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (int i = 0; i < 3; i++) {
9705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
9805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    free(Ident(malloc(kLargeMallocSize)));
996a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
10005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
10105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
10205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
10305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
10405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const size_t kManyThreadsIterations = 250;
10505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const size_t kManyThreadsNumThreads =
10605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  (SANITIZER_WORDSIZE == 32) ? 40 : 200;
10705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
10805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic void *ManyThreadsWithStatsWorker(void *arg) {
10905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  (void)arg;
11005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
11105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    for (size_t size_index = 0; size_index < 4; size_index++) {
11205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
11305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    }
11405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
11505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Just one large allocation.
11605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(Ident(malloc(1 << 20)));
11705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  return 0;
11805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
11905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
12005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
12105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  size_t before_test, after_test, i;
12205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  pthread_t threads[kManyThreadsNumThreads];
1236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  before_test = __sanitizer_get_current_allocated_bytes();
12405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (i = 0; i < kManyThreadsNumThreads; i++) {
12505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    PTHREAD_CREATE(&threads[i], 0,
12605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov                   (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
12705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
12805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (i = 0; i < kManyThreadsNumThreads; i++) {
12905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    PTHREAD_JOIN(threads[i], 0);
13005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
1316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  after_test = __sanitizer_get_current_allocated_bytes();
13205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // ASan stats also reflect memory usage of internal ASan RTL structs,
13305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // so we can't check for equality here.
13405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_LT(after_test, before_test + (1UL<<20));
13505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
13605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
13705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic void DoDoubleFree() {
13805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  int *x = Ident(new int);
13905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  delete Ident(x);
14005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  delete Ident(x);
14105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
14205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
14305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, ExitCode) {
14405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  int original_exit_code = __asan_set_error_exit_code(7);
14505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), "");
14605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EQ(7, __asan_set_error_exit_code(8));
14705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), "");
14805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));
14905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_EXIT(DoDoubleFree(),
15005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov              ::testing::ExitedWithCode(original_exit_code), "");
15105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
15205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
15305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic void MyDeathCallback() {
15405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  fprintf(stderr, "MyDeathCallback\n");
1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  fflush(0);  // On Windows, stderr doesn't flush on crash.
15605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
15705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
15805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, DeathCallbackTest) {
15905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_set_death_callback(MyDeathCallback);
16005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
16105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_set_death_callback(NULL);
16205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
16305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
16405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const char* kUseAfterPoisonErrorMessage = "use-after-poison";
16505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
16605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov#define GOOD_ACCESS(ptr, offset)  \
16705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))
16805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
16905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov#define BAD_ACCESS(ptr, offset) \
17005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))
17105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
17205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
17305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *array = Ident((char*)malloc(120));
17405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // poison array[40..80)
17505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_poison_memory_region(array + 40, 40);
17605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 39);
17705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 80);
17805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 40);
17905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 60);
18005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 79);
18105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char value;
18205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(value = Ident(array[40]), kUseAfterPoisonErrorMessage);
18305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_unpoison_memory_region(array + 40, 40);
18405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // access previously poisoned memory.
18505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 40);
18605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 79);
18705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(array);
18805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
18905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
19005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
19105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *array = Ident((char*)malloc(120));
19205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Poison [0..40) and [80..120)
19305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_poison_memory_region(array, 40);
19405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_poison_memory_region(array + 80, 40);
19505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 20);
19605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 60);
19705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 100);
19805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Poison whole array - [0..120)
19905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_poison_memory_region(array, 120);
20005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 60);
20105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Unpoison [24..96)
20205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_unpoison_memory_region(array + 24, 72);
20305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 23);
20405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 24);
20505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 60);
20605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(array, 95);
20705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(array, 96);
20805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(array);
20905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
21005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
21105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
21205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Vector of capacity 20
21305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *vec = Ident((char*)malloc(20));
21405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_poison_memory_region(vec, 20);
21505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t i = 0; i < 7; i++) {
21605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    // Simulate push_back.
21705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    __asan_unpoison_memory_region(vec + i, 1);
21805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    GOOD_ACCESS(vec, i);
21905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    BAD_ACCESS(vec, i + 1);
22005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
22105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t i = 7; i > 0; i--) {
22205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    // Simulate pop_back.
22305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    __asan_poison_memory_region(vec + i - 1, 1);
22405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    BAD_ACCESS(vec, i - 1);
22505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    if (i > 1) GOOD_ACCESS(vec, i - 2);
22605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
22705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(vec);
22805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
22905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
23005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// Make sure that each aligned block of size "2^granularity" doesn't have
23105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// "true" value before "false" value.
23205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic void MakeShadowValid(bool *shadow, int length, int granularity) {
23305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  bool can_be_poisoned = true;
23405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (int i = length - 1; i >= 0; i--) {
23505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    if (!shadow[i])
23605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      can_be_poisoned = false;
23705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    if (!can_be_poisoned)
23805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      shadow[i] = false;
23905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    if (i % (1 << granularity) == 0) {
24005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      can_be_poisoned = true;
24105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    }
24205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
24305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
24405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
24505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, PoisoningStressTest) {
24605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  const size_t kSize = 24;
24705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  bool expected[kSize];
24805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *arr = Ident((char*)malloc(kSize));
24905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t l1 = 0; l1 < kSize; l1++) {
25005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
25105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      for (size_t l2 = 0; l2 < kSize; l2++) {
25205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
25305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          // Poison [l1, l1+s1), [l2, l2+s2) and check result.
25405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          __asan_unpoison_memory_region(arr, kSize);
25505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          __asan_poison_memory_region(arr + l1, s1);
25605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          __asan_poison_memory_region(arr + l2, s2);
25705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          memset(expected, false, kSize);
25805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          memset(expected + l1, true, s1);
25905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
26005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          memset(expected + l2, true, s2);
26105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
26205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          for (size_t i = 0; i < kSize; i++) {
26305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
26405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          }
26505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
26605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          __asan_poison_memory_region(arr, kSize);
26705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          __asan_unpoison_memory_region(arr + l1, s1);
26805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          __asan_unpoison_memory_region(arr + l2, s2);
26905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          memset(expected, true, kSize);
27005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          memset(expected + l1, false, s1);
27105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
27205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          memset(expected + l2, false, s2);
27305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
27405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          for (size_t i = 0; i < kSize; i++) {
27505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
27605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          }
27705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        }
27805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      }
27905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    }
28005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
28105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(arr);
28205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
28305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
28405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, GlobalRedzones) {
28505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob1, 1 - 1);
28605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob2, 2 - 1);
28705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob3, 3 - 1);
28805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob4, 4 - 1);
28905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob5, 5 - 1);
29005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob6, 6 - 1);
29105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob7, 7 - 1);
29205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob8, 8 - 1);
29305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob9, 9 - 1);
29405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob10, 10 - 1);
29505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob11, 11 - 1);
29605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob12, 12 - 1);
29705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob13, 13 - 1);
29805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob14, 14 - 1);
29905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob15, 15 - 1);
30005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob16, 16 - 1);
30105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob17, 17 - 1);
30205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob1000, 1000 - 1);
30305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob10000, 10000 - 1);
30405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  GOOD_ACCESS(glob100000, 100000 - 1);
30505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
30605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob1, 1);
30705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob2, 2);
30805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob3, 3);
30905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob4, 4);
31005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob5, 5);
31105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob6, 6);
31205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob7, 7);
31305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob8, 8);
31405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob9, 9);
31505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob10, 10);
31605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob11, 11);
31705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob12, 12);
31805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob13, 13);
31905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob14, 14);
32005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob15, 15);
32105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob16, 16);
32205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob17, 17);
32305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob1000, 1000);
32405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob1000, 1100);  // Redzone is at least 101 bytes.
32505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob10000, 10000);
32605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob10000, 11000);  // Redzone is at least 1001 bytes.
32705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob100000, 100000);
32805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  BAD_ACCESS(glob100000, 110000);  // Redzone is at least 10001 bytes.
32905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
33005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
33105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, PoisonedRegion) {
33205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  size_t rz = 16;
33305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t size = 1; size <= 64; size++) {
33405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    char *p = new char[size];
33505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    for (size_t beg = 0; beg < size + rz; beg++) {
33605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      for (size_t end = beg; end < size + rz; end++) {
33705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);
33805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        if (beg == end) {
33905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          EXPECT_FALSE(first_poisoned);
34005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        } else if (beg < size && end <= size) {
34105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          EXPECT_FALSE(first_poisoned);
34205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        } else if (beg >= size) {
34305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          EXPECT_EQ(p + beg, first_poisoned);
34405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        } else {
34505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          EXPECT_GT(end, size);
34605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov          EXPECT_EQ(p + size, first_poisoned);
34705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov        }
34805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov      }
34905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    }
35005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    delete [] p;
35105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
35205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
35305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
35405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// This is a performance benchmark for manual runs.
35505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// asan's memset interceptor calls mem_is_zero for the entire shadow region.
35605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// the profile should look like this:
35705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//     89.10%   [.] __memset_sse2
35805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov//     10.50%   [.] __sanitizer::mem_is_zero
35905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
36005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// than memset itself.
36105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
36205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  size_t size = 1 << 20;
36305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *x = new char[size];
36405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (int i = 0; i < 100000; i++)
36505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    Ident(memset)(x, 0, size);
36605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  delete [] x;
36705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
36805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
36905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov// Same here, but we run memset with small sizes.
37005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
37105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  size_t size = 32;
37205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *x = new char[size];
37305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (int i = 0; i < 100000000; i++)
37405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    Ident(memset)(x, 0, size);
37505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  delete [] x;
37605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
37705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
37805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
37905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
38005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
38105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  char *array = Ident((char*)malloc(120));
38205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_unpoison_memory_region(array, 120);
38305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Try to unpoison not owned memory
38405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
38505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov               kInvalidUnpoisonMessage);
38605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
38705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov               kInvalidUnpoisonMessage);
38805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
38905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_poison_memory_region(array, 120);
39005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  // Try to poison not owned memory.
39105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
39205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
39305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov               kInvalidPoisonMessage);
39405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  free(array);
39505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
39605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
3972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32)  // FIXME: This should really be a lit test.
39805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonovstatic void ErrorReportCallbackOneToZ(const char *report) {
39905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  int report_len = strlen(report);
40005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  ASSERT_EQ(6, write(2, "ABCDEF", 6));
40105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  ASSERT_EQ(report_len, write(2, report, report_len));
40205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  ASSERT_EQ(6, write(2, "ABCDEF", 6));
40305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  _exit(1);
40405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
40505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
40605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
40705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
40805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),
40905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov               ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
41005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  __asan_set_error_report_callback(NULL);
41105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
4122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
41305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
41405fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey SamsonovTEST(AddressSanitizerInterface, GetOwnershipStressTest) {
41505fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  std::vector<char *> pointers;
41605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  std::vector<size_t> sizes;
41705fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  const size_t kNumMallocs = 1 << 9;
41805fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t i = 0; i < kNumMallocs; i++) {
41905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    size_t size = i * 100 + 1;
42005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    pointers.push_back((char*)malloc(size));
42105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    sizes.push_back(size);
42205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
42305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t i = 0; i < 4000000; i++) {
4246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
4256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
42605fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    size_t idx = i % kNumMallocs;
4276a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
4286a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
42905fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  }
43005fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov  for (size_t i = 0, n = pointers.size(); i < n; i++)
43105fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov    free(pointers[i]);
43205fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov}
43305fa3808f6ac96023cdf583a1a1b7220e5b451b8Alexey Samsonov
434