asan_noinst_test.cc revision 5af39e50366f1aacbebc284f572f08ad1ad07357
16f365c21d796310a9ea70d8420e6879eb5abb6aedavem//===-- asan_noinst_test.cc -----------------------------------------------===//
26f365c21d796310a9ea70d8420e6879eb5abb6aedavem//
36f365c21d796310a9ea70d8420e6879eb5abb6aedavem//                     The LLVM Compiler Infrastructure
4462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane//
5462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane// This file is distributed under the University of Illinois Open Source
6462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane// License. See LICENSE.TXT for details.
76f365c21d796310a9ea70d8420e6879eb5abb6aedavem//
86f365c21d796310a9ea70d8420e6879eb5abb6aedavem//===----------------------------------------------------------------------===//
99f23a3a1bff6c8af93e651273c9887bbf119f555Ian Romanick//
106f365c21d796310a9ea70d8420e6879eb5abb6aedavem// This file is a part of AddressSanitizer, an address sanity checker.
116f365c21d796310a9ea70d8420e6879eb5abb6aedavem//
126f365c21d796310a9ea70d8420e6879eb5abb6aedavem// This test file should be compiled w/o asan instrumentation.
136f365c21d796310a9ea70d8420e6879eb5abb6aedavem//===----------------------------------------------------------------------===//
146f365c21d796310a9ea70d8420e6879eb5abb6aedavem
156f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include "asan_allocator.h"
166f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include "asan_internal.h"
176f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include "asan_mapping.h"
186f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include "asan_stack.h"
196f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include "asan_test_utils.h"
206f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include "sanitizer/asan_interface.h"
216f365c21d796310a9ea70d8420e6879eb5abb6aedavem
226f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include <assert.h>
236f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include <stdio.h>
246f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include <stdlib.h>
256f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include <string.h>  // for memset()
266f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include <algorithm>
276f365c21d796310a9ea70d8420e6879eb5abb6aedavem#include <vector>
286f365c21d796310a9ea70d8420e6879eb5abb6aedavem
296f365c21d796310a9ea70d8420e6879eb5abb6aedavem// Simple stand-alone pseudorandom number generator.
306f365c21d796310a9ea70d8420e6879eb5abb6aedavem// Current algorithm is ANSI C linear congruential PRNG.
316f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic inline u32 my_rand(u32* state) {
326f365c21d796310a9ea70d8420e6879eb5abb6aedavem  return (*state = *state * 1103515245 + 12345) >> 16;
336f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
346f365c21d796310a9ea70d8420e6879eb5abb6aedavem
356f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic u32 global_seed = 0;
366f365c21d796310a9ea70d8420e6879eb5abb6aedavem
376f365c21d796310a9ea70d8420e6879eb5abb6aedavem
386f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, InternalSimpleDeathTest) {
396f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(exit(1), "");
406f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
416f365c21d796310a9ea70d8420e6879eb5abb6aedavem
426f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic void MallocStress(size_t n) {
436f365c21d796310a9ea70d8420e6879eb5abb6aedavem  u32 seed = my_rand(&global_seed);
446f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack1;
456f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack1.trace[0] = 0xa123;
466f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack1.trace[1] = 0xa456;
476f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack1.size = 2;
486f365c21d796310a9ea70d8420e6879eb5abb6aedavem
496f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack2;
506f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack2.trace[0] = 0xb123;
516f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack2.trace[1] = 0xb456;
526f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack2.size = 2;
536f365c21d796310a9ea70d8420e6879eb5abb6aedavem
546f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack3;
556f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack3.trace[0] = 0xc123;
566f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack3.trace[1] = 0xc456;
576f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack3.size = 2;
586f365c21d796310a9ea70d8420e6879eb5abb6aedavem
596f365c21d796310a9ea70d8420e6879eb5abb6aedavem  std::vector<void *> vec;
606f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t i = 0; i < n; i++) {
616f365c21d796310a9ea70d8420e6879eb5abb6aedavem    if ((i % 3) == 0) {
626f365c21d796310a9ea70d8420e6879eb5abb6aedavem      if (vec.empty()) continue;
636f365c21d796310a9ea70d8420e6879eb5abb6aedavem      size_t idx = my_rand(&seed) % vec.size();
646f365c21d796310a9ea70d8420e6879eb5abb6aedavem      void *ptr = vec[idx];
656f365c21d796310a9ea70d8420e6879eb5abb6aedavem      vec[idx] = vec.back();
666f365c21d796310a9ea70d8420e6879eb5abb6aedavem      vec.pop_back();
676f365c21d796310a9ea70d8420e6879eb5abb6aedavem      __asan::asan_free(ptr, &stack1);
686f365c21d796310a9ea70d8420e6879eb5abb6aedavem    } else {
696f365c21d796310a9ea70d8420e6879eb5abb6aedavem      size_t size = my_rand(&seed) % 1000 + 1;
706f365c21d796310a9ea70d8420e6879eb5abb6aedavem      switch ((my_rand(&seed) % 128)) {
716f365c21d796310a9ea70d8420e6879eb5abb6aedavem        case 0: size += 1024; break;
726f365c21d796310a9ea70d8420e6879eb5abb6aedavem        case 1: size += 2048; break;
736f365c21d796310a9ea70d8420e6879eb5abb6aedavem        case 2: size += 4096; break;
746f365c21d796310a9ea70d8420e6879eb5abb6aedavem      }
756f365c21d796310a9ea70d8420e6879eb5abb6aedavem      size_t alignment = 1 << (my_rand(&seed) % 10 + 1);
766f365c21d796310a9ea70d8420e6879eb5abb6aedavem      char *ptr = (char*)__asan::asan_memalign(alignment, size, &stack2);
776f365c21d796310a9ea70d8420e6879eb5abb6aedavem      vec.push_back(ptr);
786f365c21d796310a9ea70d8420e6879eb5abb6aedavem      ptr[0] = 0;
796f365c21d796310a9ea70d8420e6879eb5abb6aedavem      ptr[size-1] = 0;
806f365c21d796310a9ea70d8420e6879eb5abb6aedavem      ptr[size/2] = 0;
816f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
826f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
836f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t i = 0; i < vec.size(); i++)
846f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan::asan_free(vec[i], &stack3);
856f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
866f365c21d796310a9ea70d8420e6879eb5abb6aedavem
876f365c21d796310a9ea70d8420e6879eb5abb6aedavem
886f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, NoInstMallocTest) {
896f365c21d796310a9ea70d8420e6879eb5abb6aedavem#ifdef __arm__
906f365c21d796310a9ea70d8420e6879eb5abb6aedavem  MallocStress(300000);
916f365c21d796310a9ea70d8420e6879eb5abb6aedavem#else
926f365c21d796310a9ea70d8420e6879eb5abb6aedavem  MallocStress(1000000);
936f365c21d796310a9ea70d8420e6879eb5abb6aedavem#endif
946f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
956f365c21d796310a9ea70d8420e6879eb5abb6aedavem
966f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic void PrintShadow(const char *tag, uptr ptr, size_t size) {
976f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size);
98cf89f063634ff89cbd732bf67950debc94897ed9David Miller  uptr prev_shadow = 0;
996f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (sptr i = -32; i < (sptr)size + 32; i++) {
1006f365c21d796310a9ea70d8420e6879eb5abb6aedavem    uptr shadow = __asan::MemToShadow(ptr + i);
1016f365c21d796310a9ea70d8420e6879eb5abb6aedavem    if (i == 0 || i == (sptr)size)
1026f365c21d796310a9ea70d8420e6879eb5abb6aedavem      fprintf(stderr, ".");
1036f365c21d796310a9ea70d8420e6879eb5abb6aedavem    if (shadow != prev_shadow) {
1046f365c21d796310a9ea70d8420e6879eb5abb6aedavem      prev_shadow = shadow;
1056f365c21d796310a9ea70d8420e6879eb5abb6aedavem      fprintf(stderr, "%02x", (int)*(u8*)shadow);
1066f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
1076f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
1086f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "\n");
1096f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
1106f365c21d796310a9ea70d8420e6879eb5abb6aedavem
1116f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, DISABLED_InternalPrintShadow) {
1126f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t size = 1; size <= 513; size++) {
1136f365c21d796310a9ea70d8420e6879eb5abb6aedavem    char *ptr = new char[size];
1146f365c21d796310a9ea70d8420e6879eb5abb6aedavem    PrintShadow("m", (uptr)ptr, size);
1156f365c21d796310a9ea70d8420e6879eb5abb6aedavem    delete [] ptr;
1166f365c21d796310a9ea70d8420e6879eb5abb6aedavem    PrintShadow("f", (uptr)ptr, size);
1176f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
1186f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
1196f365c21d796310a9ea70d8420e6879eb5abb6aedavem
1206f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic uptr pc_array[] = {
1216f365c21d796310a9ea70d8420e6879eb5abb6aedavem#if SANITIZER_WORDSIZE == 64
1226f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf756068ULL,
1236f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf75e5abULL,
1246f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc0625b7cULL,
1256f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc05b8997ULL,
1266f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf990577ULL,
1276f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf990c56ULL,
1286f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf992f3cULL,
1296f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf950c22ULL,
1306f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc036dba0ULL,
1316f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc03638a3ULL,
1326f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc035be4aULL,
1336f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc0539c45ULL,
1346f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc0539a65ULL,
1356f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc03db9b3ULL,
1366f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc03db100ULL,
1376f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037c7b8ULL,
1386f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037bfffULL,
1396f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc038b777ULL,
1406f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc038021cULL,
1416f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037c7d1ULL,
1426f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037bfffULL,
1436f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc038b777ULL,
1446f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc038021cULL,
1456f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037c7d1ULL,
1466f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037bfffULL,
1476f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc038b777ULL,
1486f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc038021cULL,
1496f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037c7d1ULL,
1506f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc037bfffULL,
1516f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc0520d26ULL,
1526f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc009ddffULL,
1536f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbf90bb50ULL,
154cf89f063634ff89cbd732bf67950debc94897ed9David Miller  0x7effbdddfa69ULL,
1556f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbdde1fe2ULL,
1566f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbdde2424ULL,
1576f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbdde27b3ULL,
1586f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbddee53bULL,
1596f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbdde1988ULL,
1606f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbdde0904ULL,
1616f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effc106ce0dULL,
1626f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbcc3fa04ULL,
1636f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbcc3f6a4ULL,
1646f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbcc3e726ULL,
1656f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effbcc40852ULL,
1666f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7effb681ec4dULL,
1676f365c21d796310a9ea70d8420e6879eb5abb6aedavem#endif  // SANITIZER_WORDSIZE
1686f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xB0B5E768,
1696f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7B682EC1,
1706f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x367F9918,
1716f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xAE34E13,
1726f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xBA0C6C6,
1736f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x13250F46,
1746f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xA0D6A8AB,
1756f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x2B07C1A8,
1766f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x6C844F4A,
1776f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x2321B53,
1786f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x1F3D4F8F,
1796f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x3FE2924B,
1806f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xB7A2F568,
1816f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xBD23950A,
1826f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x61020930,
1836f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x33E7970C,
1846f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x405998A1,
1856f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x59F3551D,
1866f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x350E3028,
1876f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xBC55A28D,
1886f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x361F3AED,
1896f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xBEAD0F73,
1906f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xAEF28479,
1916f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x757E971F,
1926f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xAEBA450,
1936f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x43AD22F5,
1946f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x8C2C50C4,
1956f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7AD8A2E1,
1966f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x69EE4EE8,
1976f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xC08DFF,
1986f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x4BA6538,
1996f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x3708AB2,
2006f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xC24B6475,
2016f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x7C8890D7,
2026f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x6662495F,
2036f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x9B641689,
2046f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xD3596B,
2056f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0xA1049569,
2066f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x44CBC16,
2076f365c21d796310a9ea70d8420e6879eb5abb6aedavem  0x4D39C39F
2086f365c21d796310a9ea70d8420e6879eb5abb6aedavem};
2096f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2106f365c21d796310a9ea70d8420e6879eb5abb6aedavemvoid CompressStackTraceTest(size_t n_iter) {
2116f365c21d796310a9ea70d8420e6879eb5abb6aedavem  u32 seed = my_rand(&global_seed);
2126f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const size_t kNumPcs = ARRAY_SIZE(pc_array);
2136f365c21d796310a9ea70d8420e6879eb5abb6aedavem  u32 compressed[2 * kNumPcs];
2146f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2156f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t iter = 0; iter < n_iter; iter++) {
2166f365c21d796310a9ea70d8420e6879eb5abb6aedavem    std::random_shuffle(pc_array, pc_array + kNumPcs);
2176f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan::StackTrace stack0, stack1;
2186f365c21d796310a9ea70d8420e6879eb5abb6aedavem    stack0.CopyFrom(pc_array, kNumPcs);
2196f365c21d796310a9ea70d8420e6879eb5abb6aedavem    stack0.size = std::max((size_t)1, (size_t)(my_rand(&seed) % stack0.size));
2206f365c21d796310a9ea70d8420e6879eb5abb6aedavem    size_t compress_size =
2216f365c21d796310a9ea70d8420e6879eb5abb6aedavem      std::max((size_t)2, (size_t)my_rand(&seed) % (2 * kNumPcs));
2226f365c21d796310a9ea70d8420e6879eb5abb6aedavem    size_t n_frames =
2236f365c21d796310a9ea70d8420e6879eb5abb6aedavem      __asan::StackTrace::CompressStack(&stack0, compressed, compress_size);
2246f365c21d796310a9ea70d8420e6879eb5abb6aedavem    Ident(n_frames);
225cf89f063634ff89cbd732bf67950debc94897ed9David Miller    assert(n_frames <= stack0.size);
2266f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan::StackTrace::UncompressStack(&stack1, compressed, compress_size);
2276f365c21d796310a9ea70d8420e6879eb5abb6aedavem    assert(stack1.size == n_frames);
2286f365c21d796310a9ea70d8420e6879eb5abb6aedavem    for (size_t i = 0; i < stack1.size; i++) {
2296f365c21d796310a9ea70d8420e6879eb5abb6aedavem      assert(stack0.trace[i] == stack1.trace[i]);
2306f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
2316f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
2326f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
2336f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2346f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, CompressStackTraceTest) {
2356f365c21d796310a9ea70d8420e6879eb5abb6aedavem  CompressStackTraceTest(10000);
2366f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
2376f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2386f365c21d796310a9ea70d8420e6879eb5abb6aedavemvoid CompressStackTraceBenchmark(size_t n_iter) {
2396f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const size_t kNumPcs = ARRAY_SIZE(pc_array);
2406f365c21d796310a9ea70d8420e6879eb5abb6aedavem  u32 compressed[2 * kNumPcs];
2416f365c21d796310a9ea70d8420e6879eb5abb6aedavem  std::random_shuffle(pc_array, pc_array + kNumPcs);
2426f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2436f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack0;
2446f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack0.CopyFrom(pc_array, kNumPcs);
2456f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack0.size = kNumPcs;
2466f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t iter = 0; iter < n_iter; iter++) {
2476f365c21d796310a9ea70d8420e6879eb5abb6aedavem    size_t compress_size = kNumPcs;
2486f365c21d796310a9ea70d8420e6879eb5abb6aedavem    size_t n_frames =
2496f365c21d796310a9ea70d8420e6879eb5abb6aedavem      __asan::StackTrace::CompressStack(&stack0, compressed, compress_size);
2506f365c21d796310a9ea70d8420e6879eb5abb6aedavem    Ident(n_frames);
2516f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
2526f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
2536f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2546f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, CompressStackTraceBenchmark) {
2556f365c21d796310a9ea70d8420e6879eb5abb6aedavem  CompressStackTraceBenchmark(1 << 24);
2566f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
2576f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2586f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, QuarantineTest) {
2596f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack;
2606f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack.trace[0] = 0x890;
2616f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack.size = 1;
2626f365c21d796310a9ea70d8420e6879eb5abb6aedavem
263cf89f063634ff89cbd732bf67950debc94897ed9David Miller  const int size = 32;
2646f365c21d796310a9ea70d8420e6879eb5abb6aedavem  void *p = __asan::asan_malloc(size, &stack);
2656f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::asan_free(p, &stack);
2666f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t i;
2676f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t max_i = 1 << 30;
2686f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (i = 0; i < max_i; i++) {
2696f365c21d796310a9ea70d8420e6879eb5abb6aedavem    void *p1 = __asan::asan_malloc(size, &stack);
2706f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan::asan_free(p1, &stack);
2716f365c21d796310a9ea70d8420e6879eb5abb6aedavem    if (p1 == p) break;
2726f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
2736f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // fprintf(stderr, "i=%ld\n", i);
2746f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_GE(i, 100000U);
2756f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_LT(i, max_i);
2766f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
2776f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2786f365c21d796310a9ea70d8420e6879eb5abb6aedavemvoid *ThreadedQuarantineTestWorker(void *unused) {
2796f365c21d796310a9ea70d8420e6879eb5abb6aedavem  (void)unused;
2806f365c21d796310a9ea70d8420e6879eb5abb6aedavem  u32 seed = my_rand(&global_seed);
2816f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack;
2826f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack.trace[0] = 0x890;
2836f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack.size = 1;
2846f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2856f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t i = 0; i < 1000; i++) {
2866f365c21d796310a9ea70d8420e6879eb5abb6aedavem    void *p = __asan::asan_malloc(1 + (my_rand(&seed) % 4000), &stack);
2876f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan::asan_free(p, &stack);
2886f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
2896f365c21d796310a9ea70d8420e6879eb5abb6aedavem  return NULL;
2906f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
2916f365c21d796310a9ea70d8420e6879eb5abb6aedavem
2926f365c21d796310a9ea70d8420e6879eb5abb6aedavem// Check that the thread local allocators are flushed when threads are
2936f365c21d796310a9ea70d8420e6879eb5abb6aedavem// destroyed.
2946f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, ThreadedQuarantineTest) {
2956f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const int n_threads = 3000;
2966f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t mmaped1 = __asan_get_heap_size();
2976f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (int i = 0; i < n_threads; i++) {
2986f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_t t;
2996f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_create(&t, NULL, ThreadedQuarantineTestWorker, 0);
3006f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_join(t, 0);
3016f365c21d796310a9ea70d8420e6879eb5abb6aedavem    size_t mmaped2 = __asan_get_heap_size();
3026f365c21d796310a9ea70d8420e6879eb5abb6aedavem    EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));
3036f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
3046f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
3056f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3066f365c21d796310a9ea70d8420e6879eb5abb6aedavemvoid *ThreadedOneSizeMallocStress(void *unused) {
3076f365c21d796310a9ea70d8420e6879eb5abb6aedavem  (void)unused;
3086f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan::StackTrace stack;
3096f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack.trace[0] = 0x890;
3106f365c21d796310a9ea70d8420e6879eb5abb6aedavem  stack.size = 1;
3116f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const size_t kNumMallocs = 1000;
3126f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (int iter = 0; iter < 1000; iter++) {
3136f365c21d796310a9ea70d8420e6879eb5abb6aedavem    void *p[kNumMallocs];
314cf89f063634ff89cbd732bf67950debc94897ed9David Miller    for (size_t i = 0; i < kNumMallocs; i++) {
3156f365c21d796310a9ea70d8420e6879eb5abb6aedavem      p[i] = __asan::asan_malloc(32, &stack);
3166f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
3176f365c21d796310a9ea70d8420e6879eb5abb6aedavem    for (size_t i = 0; i < kNumMallocs; i++) {
3186f365c21d796310a9ea70d8420e6879eb5abb6aedavem      __asan::asan_free(p[i], &stack);
3196f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
3206f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
3216f365c21d796310a9ea70d8420e6879eb5abb6aedavem  return NULL;
3226f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
3236f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3246f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {
3256f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const int kNumThreads = 4;
3266f365c21d796310a9ea70d8420e6879eb5abb6aedavem  pthread_t t[kNumThreads];
3276f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (int i = 0; i < kNumThreads; i++) {
3286f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_create(&t[i], 0, ThreadedOneSizeMallocStress, 0);
3296f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
3306f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (int i = 0; i < kNumThreads; i++) {
3316f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_join(t[i], 0);
3326f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
3336f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
3346f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3356f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizer, MemsetWildAddressTest) {
3366f365c21d796310a9ea70d8420e6879eb5abb6aedavem  typedef void*(*memset_p)(void*, int, size_t);
3376f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Prevent inlining of memset().
3386f365c21d796310a9ea70d8420e6879eb5abb6aedavem  volatile memset_p libc_memset = (memset_p)memset;
3396f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(libc_memset((void*)(kLowShadowBeg + kPageSize), 0, 100),
3406f365c21d796310a9ea70d8420e6879eb5abb6aedavem               "unknown-crash.*low shadow");
3416f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(libc_memset((void*)(kShadowGapBeg + kPageSize), 0, 100),
3426f365c21d796310a9ea70d8420e6879eb5abb6aedavem               "unknown-crash.*shadow gap");
3436f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(libc_memset((void*)(kHighShadowBeg + kPageSize), 0, 100),
3446f365c21d796310a9ea70d8420e6879eb5abb6aedavem               "unknown-crash.*high shadow");
3456f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
3466f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3476f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
3486f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(1U, __asan_get_estimated_allocated_size(0));
3496f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const size_t sizes[] = { 1, 30, 1<<30 };
3506f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t i = 0; i < 3; i++) {
3516f365c21d796310a9ea70d8420e6879eb5abb6aedavem    EXPECT_EQ(sizes[i], __asan_get_estimated_allocated_size(sizes[i]));
3526f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
3536f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
3546f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3556f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic const char* kGetAllocatedSizeErrorMsg =
3566f365c21d796310a9ea70d8420e6879eb5abb6aedavem  "attempting to call __asan_get_allocated_size()";
3576f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3586f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
3596f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const size_t kArraySize = 100;
3606f365c21d796310a9ea70d8420e6879eb5abb6aedavem  char *array = Ident((char*)malloc(kArraySize));
3616f365c21d796310a9ea70d8420e6879eb5abb6aedavem  int *int_ptr = Ident(new int);
3626f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3636f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Allocated memory is owned by allocator. Allocated size should be
3646f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // equal to requested size.
3656f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(true, __asan_get_ownership(array));
3666f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(kArraySize, __asan_get_allocated_size(array));
3676f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(true, __asan_get_ownership(int_ptr));
3686f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(sizeof(int), __asan_get_allocated_size(int_ptr));
3696f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3706f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // We cannot call GetAllocatedSize from the memory we didn't map,
3716f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // and from the interior pointers (not returned by previous malloc).
3726f365c21d796310a9ea70d8420e6879eb5abb6aedavem  void *wild_addr = (void*)0x1;
3736f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_FALSE(__asan_get_ownership(wild_addr));
3746f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(__asan_get_allocated_size(wild_addr), kGetAllocatedSizeErrorMsg);
3756f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_FALSE(__asan_get_ownership(array + kArraySize / 2));
3766f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(__asan_get_allocated_size(array + kArraySize / 2),
3776f365c21d796310a9ea70d8420e6879eb5abb6aedavem               kGetAllocatedSizeErrorMsg);
3786f365c21d796310a9ea70d8420e6879eb5abb6aedavem
379cf89f063634ff89cbd732bf67950debc94897ed9David Miller  // NULL is not owned, but is a valid argument for __asan_get_allocated_size().
3806f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_FALSE(__asan_get_ownership(NULL));
3816f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(0U, __asan_get_allocated_size(NULL));
3826f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3836f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // When memory is freed, it's not owned, and call to GetAllocatedSize
3846f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // is forbidden.
3856f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(array);
3866f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_FALSE(__asan_get_ownership(array));
3876f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(__asan_get_allocated_size(array), kGetAllocatedSizeErrorMsg);
3886f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3896f365c21d796310a9ea70d8420e6879eb5abb6aedavem  delete int_ptr;
3906f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
3916f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3926f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
3936f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t before_malloc, after_malloc, after_free;
3946f365c21d796310a9ea70d8420e6879eb5abb6aedavem  char *array;
3956f365c21d796310a9ea70d8420e6879eb5abb6aedavem  const size_t kMallocSize = 100;
3966f365c21d796310a9ea70d8420e6879eb5abb6aedavem  before_malloc = __asan_get_current_allocated_bytes();
3976f365c21d796310a9ea70d8420e6879eb5abb6aedavem
3986f365c21d796310a9ea70d8420e6879eb5abb6aedavem  array = Ident((char*)malloc(kMallocSize));
3996f365c21d796310a9ea70d8420e6879eb5abb6aedavem  after_malloc = __asan_get_current_allocated_bytes();
4006f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
4016f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4026f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(array);
4036f365c21d796310a9ea70d8420e6879eb5abb6aedavem  after_free = __asan_get_current_allocated_bytes();
4046f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(before_malloc, after_free);
4056f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
4066f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4076f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic void DoDoubleFree() {
4086f365c21d796310a9ea70d8420e6879eb5abb6aedavem  int *x = Ident(new int);
4096f365c21d796310a9ea70d8420e6879eb5abb6aedavem  delete Ident(x);
4106f365c21d796310a9ea70d8420e6879eb5abb6aedavem  delete Ident(x);
4116f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
4126f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4136f365c21d796310a9ea70d8420e6879eb5abb6aedavem// This test is run in a separate process, so that large malloced
4146f365c21d796310a9ea70d8420e6879eb5abb6aedavem// chunk won't remain in the free lists after the test.
4156f365c21d796310a9ea70d8420e6879eb5abb6aedavem// Note: use ASSERT_* instead of EXPECT_* here.
4166f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic void RunGetHeapSizeTestAndDie() {
4176f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t old_heap_size, new_heap_size, heap_growth;
4186f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // We unlikely have have chunk of this size in free list.
4196f365c21d796310a9ea70d8420e6879eb5abb6aedavem  static const size_t kLargeMallocSize = 1 << 29;  // 512M
4206f365c21d796310a9ea70d8420e6879eb5abb6aedavem  old_heap_size = __asan_get_heap_size();
421cf89f063634ff89cbd732bf67950debc94897ed9David Miller  fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
4226f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(Ident(malloc(kLargeMallocSize)));
4236f365c21d796310a9ea70d8420e6879eb5abb6aedavem  new_heap_size = __asan_get_heap_size();
4246f365c21d796310a9ea70d8420e6879eb5abb6aedavem  heap_growth = new_heap_size - old_heap_size;
4256f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "heap growth after first malloc: %zu\n", heap_growth);
4266f365c21d796310a9ea70d8420e6879eb5abb6aedavem  ASSERT_GE(heap_growth, kLargeMallocSize);
4276f365c21d796310a9ea70d8420e6879eb5abb6aedavem  ASSERT_LE(heap_growth, 2 * kLargeMallocSize);
4286f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4296f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Now large chunk should fall into free list, and can be
4306f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // allocated without increasing heap size.
4316f365c21d796310a9ea70d8420e6879eb5abb6aedavem  old_heap_size = new_heap_size;
4326f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(Ident(malloc(kLargeMallocSize)));
4336f365c21d796310a9ea70d8420e6879eb5abb6aedavem  heap_growth = __asan_get_heap_size() - old_heap_size;
4346f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "heap growth after second malloc: %zu\n", heap_growth);
4356f365c21d796310a9ea70d8420e6879eb5abb6aedavem  ASSERT_LT(heap_growth, kLargeMallocSize);
4366f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4376f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Test passed. Now die with expected double-free.
4386f365c21d796310a9ea70d8420e6879eb5abb6aedavem  DoDoubleFree();
4396f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
4406f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4416f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, GetHeapSizeTest) {
4426f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(RunGetHeapSizeTestAndDie(), "double-free");
4436f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
4446f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4456f365c21d796310a9ea70d8420e6879eb5abb6aedavem// Note: use ASSERT_* instead of EXPECT_* here.
4466f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic void DoLargeMallocForGetFreeBytesTestAndDie() {
4476f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t old_free_bytes, new_free_bytes;
4486f365c21d796310a9ea70d8420e6879eb5abb6aedavem  static const size_t kLargeMallocSize = 1 << 29;  // 512M
4496f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // If we malloc and free a large memory chunk, it will not fall
4506f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // into quarantine and will be available for future requests.
4516f365c21d796310a9ea70d8420e6879eb5abb6aedavem  old_free_bytes = __asan_get_free_bytes();
4526f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
4536f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "free bytes before malloc: %zu\n", old_free_bytes);
4546f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(Ident(malloc(kLargeMallocSize)));
4556f365c21d796310a9ea70d8420e6879eb5abb6aedavem  new_free_bytes = __asan_get_free_bytes();
4566f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "free bytes after malloc and free: %zu\n", new_free_bytes);
4576f365c21d796310a9ea70d8420e6879eb5abb6aedavem  ASSERT_GE(new_free_bytes, old_free_bytes + kLargeMallocSize);
4586f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Test passed.
4596f365c21d796310a9ea70d8420e6879eb5abb6aedavem  DoDoubleFree();
4606f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
4616f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4626f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, GetFreeBytesTest) {
4636f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Allocate a small chunk. Now allocator probably has a lot of these
4646f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // chunks to fulfill future requests. So, future requests will decrease
4656f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // the number of free bytes. Do this only on systems where there
4666f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // is enough memory for such assumptions.
4676f365c21d796310a9ea70d8420e6879eb5abb6aedavem  if (SANITIZER_WORDSIZE == 64 && !ASAN_LOW_MEMORY) {
4686f365c21d796310a9ea70d8420e6879eb5abb6aedavem    static const size_t kNumOfChunks = 100;
4696f365c21d796310a9ea70d8420e6879eb5abb6aedavem    static const size_t kChunkSize = 100;
4706f365c21d796310a9ea70d8420e6879eb5abb6aedavem    char *chunks[kNumOfChunks];
471cf89f063634ff89cbd732bf67950debc94897ed9David Miller    size_t i;
4726f365c21d796310a9ea70d8420e6879eb5abb6aedavem    size_t old_free_bytes, new_free_bytes;
4736f365c21d796310a9ea70d8420e6879eb5abb6aedavem    chunks[0] = Ident((char*)malloc(kChunkSize));
4746f365c21d796310a9ea70d8420e6879eb5abb6aedavem    old_free_bytes = __asan_get_free_bytes();
4756f365c21d796310a9ea70d8420e6879eb5abb6aedavem    for (i = 1; i < kNumOfChunks; i++) {
4766f365c21d796310a9ea70d8420e6879eb5abb6aedavem      chunks[i] = Ident((char*)malloc(kChunkSize));
4776f365c21d796310a9ea70d8420e6879eb5abb6aedavem      new_free_bytes = __asan_get_free_bytes();
4786f365c21d796310a9ea70d8420e6879eb5abb6aedavem      EXPECT_LT(new_free_bytes, old_free_bytes);
4796f365c21d796310a9ea70d8420e6879eb5abb6aedavem      old_free_bytes = new_free_bytes;
4806f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
4816f365c21d796310a9ea70d8420e6879eb5abb6aedavem    for (i = 0; i < kNumOfChunks; i++)
4826f365c21d796310a9ea70d8420e6879eb5abb6aedavem      free(chunks[i]);
4836f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
4846f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(DoLargeMallocForGetFreeBytesTestAndDie(), "double-free");
4856f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
4866f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4876f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<20, 357};
4886f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic const size_t kManyThreadsIterations = 250;
4896f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic const size_t kManyThreadsNumThreads =
4906f365c21d796310a9ea70d8420e6879eb5abb6aedavem  (SANITIZER_WORDSIZE == 32) ? 40 : 200;
4916f365c21d796310a9ea70d8420e6879eb5abb6aedavem
4926f365c21d796310a9ea70d8420e6879eb5abb6aedavemvoid *ManyThreadsWithStatsWorker(void *arg) {
4936f365c21d796310a9ea70d8420e6879eb5abb6aedavem  (void)arg;
4946f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
4956f365c21d796310a9ea70d8420e6879eb5abb6aedavem    for (size_t size_index = 0; size_index < 4; size_index++) {
4966f365c21d796310a9ea70d8420e6879eb5abb6aedavem      free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
4976f365c21d796310a9ea70d8420e6879eb5abb6aedavem    }
4986f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
4996f365c21d796310a9ea70d8420e6879eb5abb6aedavem  return 0;
5006f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5016f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5026f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
5036f365c21d796310a9ea70d8420e6879eb5abb6aedavem  size_t before_test, after_test, i;
5046f365c21d796310a9ea70d8420e6879eb5abb6aedavem  pthread_t threads[kManyThreadsNumThreads];
5056f365c21d796310a9ea70d8420e6879eb5abb6aedavem  before_test = __asan_get_current_allocated_bytes();
5066f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (i = 0; i < kManyThreadsNumThreads; i++) {
5076f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_create(&threads[i], 0,
5086f365c21d796310a9ea70d8420e6879eb5abb6aedavem                   (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
5096f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
5106f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (i = 0; i < kManyThreadsNumThreads; i++) {
5116f365c21d796310a9ea70d8420e6879eb5abb6aedavem    pthread_join(threads[i], 0);
5126f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
5136f365c21d796310a9ea70d8420e6879eb5abb6aedavem  after_test = __asan_get_current_allocated_bytes();
5146f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // ASan stats also reflect memory usage of internal ASan RTL structs,
5156f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // so we can't check for equality here.
5166f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_LT(after_test, before_test + (1UL<<20));
5176f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5186f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5196f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, ExitCode) {
5206f365c21d796310a9ea70d8420e6879eb5abb6aedavem  int original_exit_code = __asan_set_error_exit_code(7);
5216f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), "");
5226f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(7, __asan_set_error_exit_code(8));
5236f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), "");
5246f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));
5256f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_EXIT(DoDoubleFree(),
5266f365c21d796310a9ea70d8420e6879eb5abb6aedavem              ::testing::ExitedWithCode(original_exit_code), "");
5276f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5286f365c21d796310a9ea70d8420e6879eb5abb6aedavem
529cf89f063634ff89cbd732bf67950debc94897ed9David Millerstatic void MyDeathCallback() {
5306f365c21d796310a9ea70d8420e6879eb5abb6aedavem  fprintf(stderr, "MyDeathCallback\n");
5316f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5326f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5336f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, DeathCallbackTest) {
5346f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_set_death_callback(MyDeathCallback);
5356f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
5366f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_set_death_callback(NULL);
5376f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5386f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5396f365c21d796310a9ea70d8420e6879eb5abb6aedavemstatic const char* kUseAfterPoisonErrorMessage = "use-after-poison";
5406f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5416f365c21d796310a9ea70d8420e6879eb5abb6aedavem#define GOOD_ACCESS(ptr, offset)  \
5426f365c21d796310a9ea70d8420e6879eb5abb6aedavem    EXPECT_FALSE(__asan::AddressIsPoisoned((uptr)(ptr + offset)))
5436f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5446f365c21d796310a9ea70d8420e6879eb5abb6aedavem#define BAD_ACCESS(ptr, offset) \
5456f365c21d796310a9ea70d8420e6879eb5abb6aedavem    EXPECT_TRUE(__asan::AddressIsPoisoned((uptr)(ptr + offset)))
5466f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5476f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
5486f365c21d796310a9ea70d8420e6879eb5abb6aedavem  char *array = Ident((char*)malloc(120));
5496f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // poison array[40..80)
5506f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_poison_memory_region(array + 40, 40);
5516f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 39);
5526f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 80);
5536f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 40);
5546f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 60);
5556f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 79);
5566f365c21d796310a9ea70d8420e6879eb5abb6aedavem  EXPECT_DEATH(__asan_report_error(0, 0, 0, (uptr)(array + 40), true, 1),
557cf89f063634ff89cbd732bf67950debc94897ed9David Miller               kUseAfterPoisonErrorMessage);
5586f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_unpoison_memory_region(array + 40, 40);
5596f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // access previously poisoned memory.
5606f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 40);
5616f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 79);
5626f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(array);
5636f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5646f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5656f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
5666f365c21d796310a9ea70d8420e6879eb5abb6aedavem  char *array = Ident((char*)malloc(120));
5676f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Poison [0..40) and [80..120)
5686f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_poison_memory_region(array, 40);
5696f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_poison_memory_region(array + 80, 40);
5706f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 20);
5716f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 60);
5726f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 100);
5736f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Poison whole array - [0..120)
5746f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_poison_memory_region(array, 120);
5756f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 60);
5766f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Unpoison [24..96)
5776f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_unpoison_memory_region(array + 24, 72);
5786f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 23);
5796f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 24);
5806f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 60);
5816f365c21d796310a9ea70d8420e6879eb5abb6aedavem  GOOD_ACCESS(array, 95);
5826f365c21d796310a9ea70d8420e6879eb5abb6aedavem  BAD_ACCESS(array, 96);
5836f365c21d796310a9ea70d8420e6879eb5abb6aedavem  free(array);
5846f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
5856f365c21d796310a9ea70d8420e6879eb5abb6aedavem
5866f365c21d796310a9ea70d8420e6879eb5abb6aedavemTEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
5876f365c21d796310a9ea70d8420e6879eb5abb6aedavem  // Vector of capacity 20
5886f365c21d796310a9ea70d8420e6879eb5abb6aedavem  char *vec = Ident((char*)malloc(20));
5896f365c21d796310a9ea70d8420e6879eb5abb6aedavem  __asan_poison_memory_region(vec, 20);
5906f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t i = 0; i < 7; i++) {
5916f365c21d796310a9ea70d8420e6879eb5abb6aedavem    // Simulate push_back.
5926f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan_unpoison_memory_region(vec + i, 1);
5936f365c21d796310a9ea70d8420e6879eb5abb6aedavem    GOOD_ACCESS(vec, i);
5946f365c21d796310a9ea70d8420e6879eb5abb6aedavem    BAD_ACCESS(vec, i + 1);
5956f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
5966f365c21d796310a9ea70d8420e6879eb5abb6aedavem  for (size_t i = 7; i > 0; i--) {
5976f365c21d796310a9ea70d8420e6879eb5abb6aedavem    // Simulate pop_back.
5986f365c21d796310a9ea70d8420e6879eb5abb6aedavem    __asan_poison_memory_region(vec + i - 1, 1);
5996f365c21d796310a9ea70d8420e6879eb5abb6aedavem    BAD_ACCESS(vec, i - 1);
6006f365c21d796310a9ea70d8420e6879eb5abb6aedavem    if (i > 1) GOOD_ACCESS(vec, i - 2);
6016f365c21d796310a9ea70d8420e6879eb5abb6aedavem  }
602cf89f063634ff89cbd732bf67950debc94897ed9David Miller  free(vec);
6036f365c21d796310a9ea70d8420e6879eb5abb6aedavem}
6046f365c21d796310a9ea70d8420e6879eb5abb6aedavem
6056f365c21d796310a9ea70d8420e6879eb5abb6aedavem// Make sure that each aligned block of size "2^granularity" doesn't have
606// "true" value before "false" value.
607static void MakeShadowValid(bool *shadow, int length, int granularity) {
608  bool can_be_poisoned = true;
609  for (int i = length - 1; i >= 0; i--) {
610    if (!shadow[i])
611      can_be_poisoned = false;
612    if (!can_be_poisoned)
613      shadow[i] = false;
614    if (i % (1 << granularity) == 0) {
615      can_be_poisoned = true;
616    }
617  }
618}
619
620TEST(AddressSanitizerInterface, PoisoningStressTest) {
621  const size_t kSize = 24;
622  bool expected[kSize];
623  char *arr = Ident((char*)malloc(kSize));
624  for (size_t l1 = 0; l1 < kSize; l1++) {
625    for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
626      for (size_t l2 = 0; l2 < kSize; l2++) {
627        for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
628          // Poison [l1, l1+s1), [l2, l2+s2) and check result.
629          __asan_unpoison_memory_region(arr, kSize);
630          __asan_poison_memory_region(arr + l1, s1);
631          __asan_poison_memory_region(arr + l2, s2);
632          memset(expected, false, kSize);
633          memset(expected + l1, true, s1);
634          MakeShadowValid(expected, kSize, /*granularity*/ 3);
635          memset(expected + l2, true, s2);
636          MakeShadowValid(expected, kSize, /*granularity*/ 3);
637          for (size_t i = 0; i < kSize; i++) {
638            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
639          }
640          // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
641          __asan_poison_memory_region(arr, kSize);
642          __asan_unpoison_memory_region(arr + l1, s1);
643          __asan_unpoison_memory_region(arr + l2, s2);
644          memset(expected, true, kSize);
645          memset(expected + l1, false, s1);
646          MakeShadowValid(expected, kSize, /*granularity*/ 3);
647          memset(expected + l2, false, s2);
648          MakeShadowValid(expected, kSize, /*granularity*/ 3);
649          for (size_t i = 0; i < kSize; i++) {
650            ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
651          }
652        }
653      }
654    }
655  }
656}
657
658static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
659static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
660
661TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
662  char *array = Ident((char*)malloc(120));
663  __asan_unpoison_memory_region(array, 120);
664  // Try to unpoison not owned memory
665  EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
666               kInvalidUnpoisonMessage);
667  EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
668               kInvalidUnpoisonMessage);
669
670  __asan_poison_memory_region(array, 120);
671  // Try to poison not owned memory.
672  EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
673  EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
674               kInvalidPoisonMessage);
675  free(array);
676}
677
678static void ErrorReportCallbackOneToZ(const char *report) {
679  int report_len = strlen(report);
680  ASSERT_EQ(6, write(2, "ABCDEF", 6));
681  ASSERT_EQ(report_len, write(2, report, report_len));
682  ASSERT_EQ(6, write(2, "ABCDEF", 6));
683  _exit(1);
684}
685
686TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) {
687  __asan_set_error_report_callback(ErrorReportCallbackOneToZ);
688  EXPECT_DEATH(__asan_report_error(0, 0, 0, 0, true, 1),
689               ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF");
690  __asan_set_error_report_callback(NULL);
691}
692
693TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
694  std::vector<char *> pointers;
695  std::vector<size_t> sizes;
696  const size_t kNumMallocs =
697      (SANITIZER_WORDSIZE <= 32 || ASAN_LOW_MEMORY) ? 1 << 10 : 1 << 14;
698  for (size_t i = 0; i < kNumMallocs; i++) {
699    size_t size = i * 100 + 1;
700    pointers.push_back((char*)malloc(size));
701    sizes.push_back(size);
702  }
703  for (size_t i = 0; i < 4000000; i++) {
704    EXPECT_FALSE(__asan_get_ownership(&pointers));
705    EXPECT_FALSE(__asan_get_ownership((void*)0x1234));
706    size_t idx = i % kNumMallocs;
707    EXPECT_TRUE(__asan_get_ownership(pointers[idx]));
708    EXPECT_EQ(sizes[idx], __asan_get_allocated_size(pointers[idx]));
709  }
710  for (size_t i = 0, n = pointers.size(); i < n; i++)
711    free(pointers[i]);
712}
713