asan_noinst_test.cc revision bdec26d50b27e082d109acf99f7d713abc51435e
17da8503a90c7f84787aa1ba978e2223893fa7727Alexey Samsonov//===-- asan_noinst_test.cc -----------------------------------------------===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This test file should be compiled w/o asan instrumentation.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
14d865fecddccebf898ceed24d096fc58fb29a6e57Chandler Carruth
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h"
161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h"
171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h"
181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h"
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_test_utils.h"
20d865fecddccebf898ceed24d096fc58fb29a6e57Chandler Carruth#include "sanitizer/asan_interface.h"
211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <assert.h>
231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <stdio.h>
241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <stdlib.h>
2579d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko#include <string.h>  // for memset()
261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <algorithm>
2779d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko#include <vector>
281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Simple stand-alone pseudorandom number generator.
301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Current algorithm is ANSI C linear congruential PRNG.
31ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryanystatic inline u32 my_rand(u32* state) {
321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return (*state = *state * 1103515245 + 12345) >> 16;
331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
35ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryanystatic u32 global_seed = 0;
361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
381e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, InternalSimpleDeathTest) {
391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  EXPECT_DEATH(exit(1), "");
401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic void MallocStress(size_t n) {
43ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  u32 seed = my_rand(&global_seed);
44c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack1;
451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack1.trace[0] = 0xa123;
461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack1.trace[1] = 0xa456;
471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack1.size = 2;
481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
49c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack2;
501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack2.trace[0] = 0xb123;
511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack2.trace[1] = 0xb456;
521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack2.size = 2;
531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
54c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack3;
551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack3.trace[0] = 0xc123;
561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack3.trace[1] = 0xc456;
571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack3.size = 2;
581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  std::vector<void *> vec;
601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (size_t i = 0; i < n; i++) {
611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if ((i % 3) == 0) {
621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      if (vec.empty()) continue;
631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      size_t idx = my_rand(&seed) % vec.size();
641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      void *ptr = vec[idx];
651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      vec[idx] = vec.back();
661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      vec.pop_back();
671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      __asan::asan_free(ptr, &stack1);
681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    } else {
691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      size_t size = my_rand(&seed) % 1000 + 1;
701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      switch ((my_rand(&seed) % 128)) {
711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany        case 0: size += 1024; break;
721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany        case 1: size += 2048; break;
731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany        case 2: size += 4096; break;
741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      }
751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      size_t alignment = 1 << (my_rand(&seed) % 10 + 1);
761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      char *ptr = (char*)__asan::asan_memalign(alignment, size, &stack2);
771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      vec.push_back(ptr);
781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      ptr[0] = 0;
791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      ptr[size-1] = 0;
801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      ptr[size/2] = 0;
811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (size_t i = 0; i < vec.size(); i++)
841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    __asan::asan_free(vec[i], &stack3);
851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
881e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, NoInstMallocTest) {
891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifdef __arm__
901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  MallocStress(300000);
911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#else
921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  MallocStress(1000000);
931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif
941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
963f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic void PrintShadow(const char *tag, uptr ptr, size_t size) {
971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size);
983f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  uptr prev_shadow = 0;
99ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  for (sptr i = -32; i < (sptr)size + 32; i++) {
1003f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    uptr shadow = __asan::MemToShadow(ptr + i);
101ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany    if (i == 0 || i == (sptr)size)
1021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      fprintf(stderr, ".");
1031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (shadow != prev_shadow) {
1041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      prev_shadow = shadow;
105ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany      fprintf(stderr, "%02x", (int)*(u8*)shadow);
1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
1071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  fprintf(stderr, "\n");
1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, DISABLED_InternalPrintShadow) {
1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (size_t size = 1; size <= 513; size++) {
1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    char *ptr = new char[size];
1143f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    PrintShadow("m", (uptr)ptr, size);
1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    delete [] ptr;
1163f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    PrintShadow("f", (uptr)ptr, size);
1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
1181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1203f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic uptr pc_array[] = {
1215af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany#if SANITIZER_WORDSIZE == 64
1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf756068ULL,
1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf75e5abULL,
1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc0625b7cULL,
1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc05b8997ULL,
1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf990577ULL,
1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf990c56ULL,
1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf992f3cULL,
1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf950c22ULL,
1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc036dba0ULL,
1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc03638a3ULL,
1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc035be4aULL,
1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc0539c45ULL,
1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc0539a65ULL,
1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc03db9b3ULL,
1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc03db100ULL,
1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037c7b8ULL,
1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037bfffULL,
1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc038b777ULL,
1401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc038021cULL,
1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037c7d1ULL,
1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037bfffULL,
1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc038b777ULL,
1441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc038021cULL,
1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037c7d1ULL,
1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037bfffULL,
1471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc038b777ULL,
1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc038021cULL,
1491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037c7d1ULL,
1501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc037bfffULL,
1511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc0520d26ULL,
1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc009ddffULL,
1531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbf90bb50ULL,
1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbdddfa69ULL,
1551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbdde1fe2ULL,
1561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbdde2424ULL,
1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbdde27b3ULL,
1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbddee53bULL,
1591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbdde1988ULL,
1601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbdde0904ULL,
1611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effc106ce0dULL,
1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbcc3fa04ULL,
1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbcc3f6a4ULL,
1641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbcc3e726ULL,
1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effbcc40852ULL,
1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7effb681ec4dULL,
1675af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany#endif  // SANITIZER_WORDSIZE
1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xB0B5E768,
1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7B682EC1,
1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x367F9918,
1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xAE34E13,
1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xBA0C6C6,
1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x13250F46,
1741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xA0D6A8AB,
1751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x2B07C1A8,
1761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x6C844F4A,
1771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x2321B53,
1781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x1F3D4F8F,
1791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x3FE2924B,
1801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xB7A2F568,
1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xBD23950A,
1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x61020930,
1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x33E7970C,
1841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x405998A1,
1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x59F3551D,
1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x350E3028,
1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xBC55A28D,
1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x361F3AED,
1891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xBEAD0F73,
1901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xAEF28479,
1911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x757E971F,
1921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xAEBA450,
1931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x43AD22F5,
1941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x8C2C50C4,
1951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7AD8A2E1,
1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x69EE4EE8,
1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xC08DFF,
1981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x4BA6538,
1991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x3708AB2,
2001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xC24B6475,
2011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x7C8890D7,
2021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x6662495F,
2031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x9B641689,
2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xD3596B,
2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0xA1049569,
2061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x44CBC16,
2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  0x4D39C39F
2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany};
2091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid CompressStackTraceTest(size_t n_iter) {
211ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  u32 seed = my_rand(&global_seed);
212c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  const size_t kNumPcs = ARRAY_SIZE(pc_array);
213ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  u32 compressed[2 * kNumPcs];
2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (size_t iter = 0; iter < n_iter; iter++) {
2161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    std::random_shuffle(pc_array, pc_array + kNumPcs);
217c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany    __asan::StackTrace stack0, stack1;
2181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    stack0.CopyFrom(pc_array, kNumPcs);
2193f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    stack0.size = std::max((size_t)1, (size_t)(my_rand(&seed) % stack0.size));
2201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t compress_size =
2211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      std::max((size_t)2, (size_t)my_rand(&seed) % (2 * kNumPcs));
2221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t n_frames =
223c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany      __asan::StackTrace::CompressStack(&stack0, compressed, compress_size);
2241a7741b4e3c50a986502507fa8055475dd0fa0d0Alexey Samsonov    Ident(n_frames);
2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    assert(n_frames <= stack0.size);
226c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany    __asan::StackTrace::UncompressStack(&stack1, compressed, compress_size);
2271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    assert(stack1.size == n_frames);
2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    for (size_t i = 0; i < stack1.size; i++) {
2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      assert(stack0.trace[i] == stack1.trace[i]);
2301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
2311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2341e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, CompressStackTraceTest) {
2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  CompressStackTraceTest(10000);
2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid CompressStackTraceBenchmark(size_t n_iter) {
239c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  const size_t kNumPcs = ARRAY_SIZE(pc_array);
240ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  u32 compressed[2 * kNumPcs];
2411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  std::random_shuffle(pc_array, pc_array + kNumPcs);
2421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
243c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack0;
2441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack0.CopyFrom(pc_array, kNumPcs);
2451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack0.size = kNumPcs;
2461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (size_t iter = 0; iter < n_iter; iter++) {
2471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t compress_size = kNumPcs;
2481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t n_frames =
249c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany      __asan::StackTrace::CompressStack(&stack0, compressed, compress_size);
2501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    Ident(n_frames);
2511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
2521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, CompressStackTraceBenchmark) {
2551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  CompressStackTraceBenchmark(1 << 24);
2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2581e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, QuarantineTest) {
259c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack;
2601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack.trace[0] = 0x890;
2611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack.size = 1;
2621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const int size = 32;
2641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  void *p = __asan::asan_malloc(size, &stack);
2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  __asan::asan_free(p, &stack);
2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t i;
2671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t max_i = 1 << 30;
2681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (i = 0; i < max_i; i++) {
2691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    void *p1 = __asan::asan_malloc(size, &stack);
2701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    __asan::asan_free(p1, &stack);
2711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    if (p1 == p) break;
2721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
2731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // fprintf(stderr, "i=%ld\n", i);
2741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  EXPECT_GE(i, 100000U);
2751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  EXPECT_LT(i, max_i);
2761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *ThreadedQuarantineTestWorker(void *unused) {
2791a7741b4e3c50a986502507fa8055475dd0fa0d0Alexey Samsonov  (void)unused;
280ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  u32 seed = my_rand(&global_seed);
281c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack;
2821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack.trace[0] = 0x890;
2831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack.size = 1;
2841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (size_t i = 0; i < 1000; i++) {
2861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    void *p = __asan::asan_malloc(1 + (my_rand(&seed) % 4000), &stack);
2871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    __asan::asan_free(p, &stack);
2881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
2891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return NULL;
2901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Check that the thread local allocators are flushed when threads are
2931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// destroyed.
2941e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, ThreadedQuarantineTest) {
2951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const int n_threads = 3000;
2961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  size_t mmaped1 = __asan_get_heap_size();
2971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (int i = 0; i < n_threads; i++) {
2981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    pthread_t t;
2991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    pthread_create(&t, NULL, ThreadedQuarantineTestWorker, 0);
3001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    pthread_join(t, 0);
3011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    size_t mmaped2 = __asan_get_heap_size();
3021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));
3031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
3041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
3051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
3061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *ThreadedOneSizeMallocStress(void *unused) {
3071a7741b4e3c50a986502507fa8055475dd0fa0d0Alexey Samsonov  (void)unused;
308c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryany  __asan::StackTrace stack;
3091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack.trace[0] = 0x890;
3101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  stack.size = 1;
3111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const size_t kNumMallocs = 1000;
3121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (int iter = 0; iter < 1000; iter++) {
3131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    void *p[kNumMallocs];
3141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    for (size_t i = 0; i < kNumMallocs; i++) {
3151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      p[i] = __asan::asan_malloc(32, &stack);
3161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
3171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    for (size_t i = 0; i < kNumMallocs; i++) {
3181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany      __asan::asan_free(p[i], &stack);
3191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    }
3201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
3211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return NULL;
3221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
3231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
3241e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyTEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {
3251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  const int kNumThreads = 4;
3261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  pthread_t t[kNumThreads];
3271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (int i = 0; i < kNumThreads; i++) {
3281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    pthread_create(&t[i], 0, ThreadedOneSizeMallocStress, 0);
3291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
3301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  for (int i = 0; i < kNumThreads; i++) {
3311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany    pthread_join(t[i], 0);
3321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  }
3331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
334bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
33579d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander PotapenkoTEST(AddressSanitizer, MemsetWildAddressTest) {
33679d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko  typedef void*(*memset_p)(void*, int, size_t);
33779d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko  // Prevent inlining of memset().
33879d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko  volatile memset_p libc_memset = (memset_p)memset;
339bdec26d50b27e082d109acf99f7d713abc51435eKostya Serebryany  EXPECT_DEATH(libc_memset((void*)(kLowShadowBeg + 200), 0, 100),
34079d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko               "unknown-crash.*low shadow");
341bdec26d50b27e082d109acf99f7d713abc51435eKostya Serebryany  EXPECT_DEATH(libc_memset((void*)(kShadowGapBeg + 200), 0, 100),
34279d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko               "unknown-crash.*shadow gap");
343bdec26d50b27e082d109acf99f7d713abc51435eKostya Serebryany  EXPECT_DEATH(libc_memset((void*)(kHighShadowBeg + 200), 0, 100),
34479d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko               "unknown-crash.*high shadow");
34579d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko}
34679d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko
347bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
348d00ecb64892dcb03c5ae93a654da669b96753b01Alexey Samsonov  EXPECT_EQ(1U, __asan_get_estimated_allocated_size(0));
349bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  const size_t sizes[] = { 1, 30, 1<<30 };
350bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t i = 0; i < 3; i++) {
351bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_EQ(sizes[i], __asan_get_estimated_allocated_size(sizes[i]));
352bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
353bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
354bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
355bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic const char* kGetAllocatedSizeErrorMsg =
356bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  "attempting to call __asan_get_allocated_size()";
357bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
358bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
359bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  const size_t kArraySize = 100;
360bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *array = Ident((char*)malloc(kArraySize));
361bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  int *int_ptr = Ident(new int);
362bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
363bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Allocated memory is owned by allocator. Allocated size should be
364bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // equal to requested size.
365bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(true, __asan_get_ownership(array));
366bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(kArraySize, __asan_get_allocated_size(array));
367bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(true, __asan_get_ownership(int_ptr));
368bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(sizeof(int), __asan_get_allocated_size(int_ptr));
369bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
370bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // We cannot call GetAllocatedSize from the memory we didn't map,
371bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // and from the interior pointers (not returned by previous malloc).
372bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  void *wild_addr = (void*)0x1;
373de55be3899b994731ba2d9e168281d608dab3048Alexey Samsonov  EXPECT_FALSE(__asan_get_ownership(wild_addr));
374bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_get_allocated_size(wild_addr), kGetAllocatedSizeErrorMsg);
37568e8acab81a43ccf849add9272a761dc6b73ee8dKostya Serebryany  EXPECT_FALSE(__asan_get_ownership(array + kArraySize / 2));
376bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_get_allocated_size(array + kArraySize / 2),
377bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany               kGetAllocatedSizeErrorMsg);
378bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
379bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // NULL is not owned, but is a valid argument for __asan_get_allocated_size().
38068e8acab81a43ccf849add9272a761dc6b73ee8dKostya Serebryany  EXPECT_FALSE(__asan_get_ownership(NULL));
381d00ecb64892dcb03c5ae93a654da669b96753b01Alexey Samsonov  EXPECT_EQ(0U, __asan_get_allocated_size(NULL));
382bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
383bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // When memory is freed, it's not owned, and call to GetAllocatedSize
384bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // is forbidden.
385bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(array);
386de55be3899b994731ba2d9e168281d608dab3048Alexey Samsonov  EXPECT_FALSE(__asan_get_ownership(array));
387bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_get_allocated_size(array), kGetAllocatedSizeErrorMsg);
388bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
389bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  delete int_ptr;
390bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
391bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
392bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
393bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  size_t before_malloc, after_malloc, after_free;
394bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *array;
395bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  const size_t kMallocSize = 100;
396bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  before_malloc = __asan_get_current_allocated_bytes();
397bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
398bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  array = Ident((char*)malloc(kMallocSize));
399bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  after_malloc = __asan_get_current_allocated_bytes();
400bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
401bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
402bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(array);
403bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  after_free = __asan_get_current_allocated_bytes();
404bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(before_malloc, after_free);
405bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
406bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
407bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic void DoDoubleFree() {
408bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  int *x = Ident(new int);
409bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  delete Ident(x);
410bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  delete Ident(x);
411bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
412bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
413bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany// This test is run in a separate process, so that large malloced
414bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany// chunk won't remain in the free lists after the test.
415bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany// Note: use ASSERT_* instead of EXPECT_* here.
416bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic void RunGetHeapSizeTestAndDie() {
417bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  size_t old_heap_size, new_heap_size, heap_growth;
418bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // We unlikely have have chunk of this size in free list.
419bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  static const size_t kLargeMallocSize = 1 << 29;  // 512M
420bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  old_heap_size = __asan_get_heap_size();
421bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
422bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(Ident(malloc(kLargeMallocSize)));
423bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  new_heap_size = __asan_get_heap_size();
424bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  heap_growth = new_heap_size - old_heap_size;
425bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "heap growth after first malloc: %zu\n", heap_growth);
426bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  ASSERT_GE(heap_growth, kLargeMallocSize);
427bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  ASSERT_LE(heap_growth, 2 * kLargeMallocSize);
428bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
429bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Now large chunk should fall into free list, and can be
430bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // allocated without increasing heap size.
431bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  old_heap_size = new_heap_size;
432bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(Ident(malloc(kLargeMallocSize)));
433bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  heap_growth = __asan_get_heap_size() - old_heap_size;
434bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "heap growth after second malloc: %zu\n", heap_growth);
435bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  ASSERT_LT(heap_growth, kLargeMallocSize);
436bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
437bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Test passed. Now die with expected double-free.
438bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  DoDoubleFree();
439bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
440bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
441bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, GetHeapSizeTest) {
442bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(RunGetHeapSizeTestAndDie(), "double-free");
443bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
444bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
445bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany// Note: use ASSERT_* instead of EXPECT_* here.
446bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic void DoLargeMallocForGetFreeBytesTestAndDie() {
447bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  size_t old_free_bytes, new_free_bytes;
448bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  static const size_t kLargeMallocSize = 1 << 29;  // 512M
449bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // If we malloc and free a large memory chunk, it will not fall
450bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // into quarantine and will be available for future requests.
451bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  old_free_bytes = __asan_get_free_bytes();
452bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
453bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "free bytes before malloc: %zu\n", old_free_bytes);
454bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(Ident(malloc(kLargeMallocSize)));
455bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  new_free_bytes = __asan_get_free_bytes();
456bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "free bytes after malloc and free: %zu\n", new_free_bytes);
457bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  ASSERT_GE(new_free_bytes, old_free_bytes + kLargeMallocSize);
458bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Test passed.
459bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  DoDoubleFree();
460bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
461bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
462bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, GetFreeBytesTest) {
463bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Allocate a small chunk. Now allocator probably has a lot of these
464bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // chunks to fulfill future requests. So, future requests will decrease
465f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov  // the number of free bytes. Do this only on systems where there
466f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov  // is enough memory for such assumptions.
4675af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany  if (SANITIZER_WORDSIZE == 64 && !ASAN_LOW_MEMORY) {
468f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    static const size_t kNumOfChunks = 100;
469f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    static const size_t kChunkSize = 100;
470f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    char *chunks[kNumOfChunks];
471f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    size_t i;
472f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    size_t old_free_bytes, new_free_bytes;
473f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    chunks[0] = Ident((char*)malloc(kChunkSize));
474f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    old_free_bytes = __asan_get_free_bytes();
475f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    for (i = 1; i < kNumOfChunks; i++) {
476f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov      chunks[i] = Ident((char*)malloc(kChunkSize));
477f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov      new_free_bytes = __asan_get_free_bytes();
478f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov      EXPECT_LT(new_free_bytes, old_free_bytes);
479f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov      old_free_bytes = new_free_bytes;
480f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    }
481f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov    for (i = 0; i < kNumOfChunks; i++)
482f70848decb000cc0e4c05a27eed78865d2f38555Alexey Samsonov      free(chunks[i]);
483bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
484bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(DoLargeMallocForGetFreeBytesTestAndDie(), "double-free");
485bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
486bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
487bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<20, 357};
488bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic const size_t kManyThreadsIterations = 250;
4895af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryanystatic const size_t kManyThreadsNumThreads =
4905af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany  (SANITIZER_WORDSIZE == 32) ? 40 : 200;
491bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
492bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanyvoid *ManyThreadsWithStatsWorker(void *arg) {
4931a7741b4e3c50a986502507fa8055475dd0fa0d0Alexey Samsonov  (void)arg;
494bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
495bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    for (size_t size_index = 0; size_index < 4; size_index++) {
496bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany      free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
497bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    }
498bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
499bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  return 0;
500bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
501bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
502bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
503bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  size_t before_test, after_test, i;
504bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  pthread_t threads[kManyThreadsNumThreads];
505bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  before_test = __asan_get_current_allocated_bytes();
506bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (i = 0; i < kManyThreadsNumThreads; i++) {
507bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    pthread_create(&threads[i], 0,
508bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany                   (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
509bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
510bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (i = 0; i < kManyThreadsNumThreads; i++) {
511bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    pthread_join(threads[i], 0);
512bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
513bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  after_test = __asan_get_current_allocated_bytes();
514bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // ASan stats also reflect memory usage of internal ASan RTL structs,
515bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // so we can't check for equality here.
516bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_LT(after_test, before_test + (1UL<<20));
517bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
518bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
519bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, ExitCode) {
520bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  int original_exit_code = __asan_set_error_exit_code(7);
521bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), "");
522bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(7, __asan_set_error_exit_code(8));
523bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), "");
524bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));
525bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_EXIT(DoDoubleFree(),
526bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany              ::testing::ExitedWithCode(original_exit_code), "");
527bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
528bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
529bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic void MyDeathCallback() {
530bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  fprintf(stderr, "MyDeathCallback\n");
531bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
532bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
533bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, DeathCallbackTest) {
534bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_set_death_callback(MyDeathCallback);
535bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
536bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_set_death_callback(NULL);
537bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
538bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
539bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic const char* kUseAfterPoisonErrorMessage = "use-after-poison";
540bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
541bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany#define GOOD_ACCESS(ptr, offset)  \
542bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_FALSE(__asan::AddressIsPoisoned((uptr)(ptr + offset)))
543bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
544bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany#define BAD_ACCESS(ptr, offset) \
545bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_TRUE(__asan::AddressIsPoisoned((uptr)(ptr + offset)))
546bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
547bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
548bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *array = Ident((char*)malloc(120));
549bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // poison array[40..80)
550bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_poison_memory_region(array + 40, 40);
551bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 39);
552bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 80);
553bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 40);
554bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 60);
555bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 79);
556bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_report_error(0, 0, 0, (uptr)(array + 40), true, 1),
557bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany               kUseAfterPoisonErrorMessage);
558bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_unpoison_memory_region(array + 40, 40);
559bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // access previously poisoned memory.
560bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 40);
561bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 79);
562bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(array);
563bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
564bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
565bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
566bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *array = Ident((char*)malloc(120));
567bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Poison [0..40) and [80..120)
568bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_poison_memory_region(array, 40);
569bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_poison_memory_region(array + 80, 40);
570bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 20);
571bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 60);
572bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 100);
573bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Poison whole array - [0..120)
574bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_poison_memory_region(array, 120);
575bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 60);
576bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Unpoison [24..96)
577bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_unpoison_memory_region(array + 24, 72);
578bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 23);
579bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 24);
580bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 60);
581bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  GOOD_ACCESS(array, 95);
582bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  BAD_ACCESS(array, 96);
583bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(array);
584bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
585bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
586bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
587bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Vector of capacity 20
588bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *vec = Ident((char*)malloc(20));
589bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_poison_memory_region(vec, 20);
590bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t i = 0; i < 7; i++) {
591bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    // Simulate push_back.
592bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    __asan_unpoison_memory_region(vec + i, 1);
593bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    GOOD_ACCESS(vec, i);
594bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    BAD_ACCESS(vec, i + 1);
595bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
596bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t i = 7; i > 0; i--) {
597bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    // Simulate pop_back.
598bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    __asan_poison_memory_region(vec + i - 1, 1);
599bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    BAD_ACCESS(vec, i - 1);
600bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    if (i > 1) GOOD_ACCESS(vec, i - 2);
601bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
602bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(vec);
603bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
604bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
605bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany// Make sure that each aligned block of size "2^granularity" doesn't have
606bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany// "true" value before "false" value.
607bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic void MakeShadowValid(bool *shadow, int length, int granularity) {
608bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  bool can_be_poisoned = true;
609bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (int i = length - 1; i >= 0; i--) {
61063201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov    if (!shadow[i])
61163201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov      can_be_poisoned = false;
61263201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov    if (!can_be_poisoned)
61363201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov      shadow[i] = false;
614bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    if (i % (1 << granularity) == 0) {
615bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany      can_be_poisoned = true;
616bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    }
617bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
618bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
619bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
620bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, PoisoningStressTest) {
621bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  const size_t kSize = 24;
622bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  bool expected[kSize];
623bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *arr = Ident((char*)malloc(kSize));
624bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t l1 = 0; l1 < kSize; l1++) {
625bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
626bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany      for (size_t l2 = 0; l2 < kSize; l2++) {
627bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany        for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
628bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          // Poison [l1, l1+s1), [l2, l2+s2) and check result.
629bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          __asan_unpoison_memory_region(arr, kSize);
630bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          __asan_poison_memory_region(arr + l1, s1);
631bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          __asan_poison_memory_region(arr + l2, s2);
632bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          memset(expected, false, kSize);
633bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          memset(expected + l1, true, s1);
63463201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
635bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          memset(expected + l2, true, s2);
63663201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
637bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          for (size_t i = 0; i < kSize; i++) {
638bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
639bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          }
640bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
641bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          __asan_poison_memory_region(arr, kSize);
642bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          __asan_unpoison_memory_region(arr + l1, s1);
643bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          __asan_unpoison_memory_region(arr + l2, s2);
644bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          memset(expected, true, kSize);
645bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          memset(expected + l1, false, s1);
64663201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
647bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          memset(expected + l2, false, s2);
64863201b127e21d6fbfb6de62d0e44a5de01288153Alexey Samsonov          MakeShadowValid(expected, kSize, /*granularity*/ 3);
649bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          for (size_t i = 0; i < kSize; i++) {
650bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
651bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany          }
652bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany        }
653bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany      }
654bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    }
655bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
656bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
657bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
658bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
659bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
660bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
661bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
662bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  char *array = Ident((char*)malloc(120));
663bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_unpoison_memory_region(array, 120);
664bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Try to unpoison not owned memory
665bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
666bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany               kInvalidUnpoisonMessage);
667bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
668bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany               kInvalidUnpoisonMessage);
669bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
670bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_poison_memory_region(array, 120);
671bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  // Try to poison not owned memory.
672bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
673bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
674bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany               kInvalidPoisonMessage);
675bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  free(array);
676bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
677bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
678bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryanystatic void ErrorReportCallbackOneToZ(const char *report) {
679b43d6a8ca10b9af8a903e8726003ae7767f9e823Alexey Samsonov  int report_len = strlen(report);
680b43d6a8ca10b9af8a903e8726003ae7767f9e823Alexey Samsonov  ASSERT_EQ(6, write(2, "ABCDEF", 6));
681b43d6a8ca10b9af8a903e8726003ae7767f9e823Alexey Samsonov  ASSERT_EQ(report_len, write(2, report, report_len));
682b43d6a8ca10b9af8a903e8726003ae7767f9e823Alexey Samsonov  ASSERT_EQ(6, write(2, "ABCDEF", 6));
6832c29212c42d457ade0bbd1d01de92195dd9ce925Kostya Serebryany  _exit(1);
684bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
685bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
686bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
687bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
6882c29212c42d457ade0bbd1d01de92195dd9ce925Kostya Serebryany  EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),
6892c29212c42d457ade0bbd1d01de92195dd9ce925Kostya Serebryany               ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
690bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  __asan_set_error_report_callback(NULL);
691bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
692bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany
693bff533684731c89bd5e99d0cf950a86c21a342e8Kostya SerebryanyTEST(AddressSanitizerInterface, GetOwnershipStressTest) {
694bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  std::vector<char *> pointers;
695bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  std::vector<size_t> sizes;
696bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  const size_t kNumMallocs =
6975af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany      (SANITIZER_WORDSIZE <= 32 || ASAN_LOW_MEMORY) ? 1 << 10 : 1 << 14;
698bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t i = 0; i < kNumMallocs; i++) {
699bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    size_t size = i * 100 + 1;
700bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    pointers.push_back((char*)malloc(size));
701bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    sizes.push_back(size);
702bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
703bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t i = 0; i < 4000000; i++) {
704bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_FALSE(__asan_get_ownership(&pointers));
705bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_FALSE(__asan_get_ownership((void*)0x1234));
706bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    size_t idx = i % kNumMallocs;
707bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_TRUE(__asan_get_ownership(pointers[idx]));
708bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    EXPECT_EQ(sizes[idx], __asan_get_allocated_size(pointers[idx]));
709bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  }
710bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany  for (size_t i = 0, n = pointers.size(); i < n; i++)
711bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany    free(pointers[i]);
712bff533684731c89bd5e99d0cf950a86c21a342e8Kostya Serebryany}
713