Coverage for /Syzygy/agent/asan/rtl_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.4%3113130.C++test

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include <windows.h>
  16    :  
  17    :  #include "gtest/gtest.h"
  18    :  #include "syzygy/agent/asan/heap_checker.h"
  19    :  #include "syzygy/agent/asan/rtl_impl.h"
  20    :  #include "syzygy/agent/asan/runtime.h"
  21    :  #include "syzygy/agent/asan/unittest_util.h"
  22    :  
  23    :  namespace agent {
  24    :  namespace asan {
  25    :  
  26    :  namespace {
  27    :  
  28    :  using testing::AsanBlockInfoVector;
  29    :  using testing::MemoryAccessorTester;
  30    :  using testing::ScopedAsanAlloc;
  31    :  
  32    :  // An arbitrary size for the buffer we allocate in the different unittests.
  33    :  const size_t kAllocSize = 13;
  34    :  
  35    :  class AsanRtlTest : public testing::TestAsanRtl {
  36    :   public:
  37    :    AsanRtlTest() : memory_src_(NULL), memory_dst_(NULL), memory_length_(0),
  38  E :        memory_size_(0) { }
  39    :  
  40  E :    void SetUp() override {
  41  E :      testing::TestAsanRtl::SetUp();
  42    :  
  43    :      // Setup the callback to detect invalid accesses.
  44  E :      SetCallBackFunction(&MemoryAccessorTester::AsanErrorCallback);
  45  E :    }
  46    :  
  47    :   protected:
  48    :    void AllocMemoryBuffers(int32 length, int32 element_size);
  49    :    void FreeMemoryBuffers();
  50    :  
  51    :    // Memory buffers used to test special instructions.
  52    :    void* memory_src_;
  53    :    void* memory_dst_;
  54    :    int32 memory_length_;
  55    :    int32 memory_size_;
  56    :  };
  57    :  
  58  E :  void AsanRtlTest::AllocMemoryBuffers(int32 length, int32 element_size) {
  59  E :    ASSERT_EQ(reinterpret_cast<void*>(NULL), memory_src_);
  60  E :    ASSERT_EQ(reinterpret_cast<void*>(NULL), memory_dst_);
  61  E :    ASSERT_EQ(0, memory_length_);
  62  E :    ASSERT_EQ(0, memory_size_);
  63    :  
  64    :    // Keep track of memory size.
  65  E :    memory_length_ = length;
  66  E :    memory_size_ = length * element_size;
  67    :  
  68    :    // Allocate memory space.
  69  E :    memory_src_ = HeapAllocFunction(heap_, 0, memory_size_);
  70  E :    ASSERT_TRUE(memory_src_ != NULL);
  71  E :    memory_dst_ = HeapAllocFunction(heap_, 0, memory_size_);
  72  E :    ASSERT_TRUE(memory_dst_ != NULL);
  73    :  
  74    :    // Initialize memory.
  75  E :    ::memset(memory_src_, 0, memory_size_);
  76  E :    ::memset(memory_dst_, 0, memory_size_);
  77  E :  }
  78    :  
  79  E :  void AsanRtlTest::FreeMemoryBuffers() {
  80  E :    ASSERT_NE(reinterpret_cast<void*>(NULL), memory_src_);
  81  E :    ASSERT_NE(reinterpret_cast<void*>(NULL), memory_dst_);
  82    :  
  83  E :    ASSERT_TRUE(HeapFreeFunction(heap_, 0, memory_src_));
  84  E :    ASSERT_TRUE(HeapFreeFunction(heap_, 0, memory_dst_));
  85    :  
  86  E :    memory_length_ = 0;
  87  E :    memory_size_ = 0;
  88  E :    memory_src_ = NULL;
  89  E :    memory_dst_ = NULL;
  90  E :  }
  91    :  
  92    :  }  // namespace
  93    :  
  94  E :  TEST_F(AsanRtlTest, GetProcessHeap) {
  95  E :    agent::asan::AsanRuntime* runtime = GetActiveRuntimeFunction();
  96  E :    ASSERT_NE(reinterpret_cast<agent::asan::AsanRuntime*>(NULL), runtime);
  97  E :    HANDLE asan_heap_handle = GetProcessHeapFunction();
  98  E :    EXPECT_NE(static_cast<HANDLE>(NULL), asan_heap_handle);
  99    :    EXPECT_EQ(reinterpret_cast<HANDLE>(runtime->GetProcessHeap()),
 100  E :                                       asan_heap_handle);
 101  E :  }
 102    :  
 103  E :  TEST_F(AsanRtlTest, AsanCheckGoodAccess) {
 104    :    FARPROC check_access_fn =
 105  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 106  E :    ASSERT_TRUE(check_access_fn != NULL);
 107    :  
 108    :    // Run through access checking an allocation that's larger than our
 109    :    // block size (8), but not a multiple thereof to exercise all paths
 110    :    // in the access check function (save for the failure path).
 111  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
 112  E :    ASSERT_TRUE(mem.get() != NULL);
 113    :  
 114  E :    MemoryAccessorTester tester;
 115  E :    for (size_t i = 0; i < kAllocSize; ++i) {
 116    :      ASSERT_NO_FATAL_FAILURE(
 117  E :          tester.CheckAccessAndCompareContexts(check_access_fn, mem.get() + i));
 118  E :    }
 119  E :  }
 120    :  
 121  E :  TEST_F(AsanRtlTest, AsanCheckHeapBufferOverflow) {
 122    :    FARPROC check_access_fn =
 123  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 124  E :    ASSERT_TRUE(check_access_fn != NULL);
 125    :  
 126  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
 127  E :    ASSERT_TRUE(mem.get() != NULL);
 128    :  
 129  E :    MemoryAccessorTester tester;
 130    :    tester.AssertMemoryErrorIsDetected(
 131  E :        check_access_fn, mem.get() + kAllocSize, HEAP_BUFFER_OVERFLOW);
 132  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 133  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 134  E :  }
 135    :  
 136  E :  TEST_F(AsanRtlTest, AsanCheckHeapBufferUnderflow) {
 137    :    FARPROC check_access_fn =
 138  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 139  E :    ASSERT_TRUE(check_access_fn != NULL);
 140    :  
 141  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
 142  E :    ASSERT_TRUE(mem.get() != NULL);
 143    :  
 144  E :    MemoryAccessorTester tester;
 145    :    tester.AssertMemoryErrorIsDetected(
 146  E :        check_access_fn, mem.get() - 1, HEAP_BUFFER_UNDERFLOW);
 147  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 148  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 149  E :  }
 150    :  
 151  E :  TEST_F(AsanRtlTest, AsanCheckUseAfterFree) {
 152    :    FARPROC check_access_fn =
 153  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 154  E :    ASSERT_TRUE(check_access_fn != NULL);
 155    :  
 156  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
 157  E :    ASSERT_TRUE(mem.get() != NULL);
 158    :  
 159  E :    uint8* mem_ptr = mem.get();
 160  E :    mem.reset(NULL);
 161    :  
 162  E :    MemoryAccessorTester tester;
 163  E :    tester.AssertMemoryErrorIsDetected(check_access_fn, mem_ptr, USE_AFTER_FREE);
 164  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 165  E :    EXPECT_TRUE(LogContains("freed here"));
 166  E :    EXPECT_TRUE(LogContains(kHeapUseAfterFree));
 167  E :  }
 168    :  
 169  E :  TEST_F(AsanRtlTest, AsanCheckDoubleFree) {
 170    :    FARPROC check_access_fn =
 171  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 172  E :    ASSERT_TRUE(check_access_fn != NULL);
 173    :  
 174  E :    uint8* mem_ptr = NULL;
 175    :    {
 176  E :      ScopedAsanAlloc<uint8> mem(this, kAllocSize);
 177  E :      ASSERT_TRUE(mem.get() != NULL);
 178  E :      mem_ptr = mem.get();
 179  E :    }
 180    :  
 181  E :    MemoryAccessorTester tester;
 182  E :    tester.set_expected_error_type(DOUBLE_FREE);
 183  E :    EXPECT_FALSE(HeapFreeFunction(heap_, 0, mem_ptr));
 184  E :    EXPECT_TRUE(tester.memory_error_detected());
 185  E :    EXPECT_TRUE(LogContains(kAttemptingDoubleFree));
 186  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 187  E :    EXPECT_TRUE(LogContains("freed here"));
 188  E :  }
 189    :  
 190  E :  TEST_F(AsanRtlTest, AsanCheckWildAccess) {
 191    :    FARPROC check_access_fn =
 192  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 193  E :    ASSERT_TRUE(check_access_fn != NULL);
 194    :  
 195  E :    MemoryAccessorTester tester;
 196    :    tester.AssertMemoryErrorIsDetected(
 197  E :        check_access_fn, reinterpret_cast<void*>(0x80000000), WILD_ACCESS);
 198  E :    EXPECT_TRUE(LogContains(kWildAccess));
 199  E :  }
 200    :  
 201    :  // It is not possible to test the near-nullptr access with heap corruption
 202    :  // execution path since it depends on the unhandled exception filter which is
 203    :  // not installed in the rtl library.
 204  E :  TEST_F(AsanRtlTest, AsanIgnoreInvalidAccess) {
 205    :    FARPROC check_access_fn =
 206  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 207  E :    ASSERT_TRUE(check_access_fn != NULL);
 208    :  
 209    :    // A near-nullptr access should not be reported by SyzyASAN.
 210  E :    MemoryAccessorTester tester;
 211  E :    tester.CheckAccessAndCompareContexts(check_access_fn, nullptr);
 212  E :    EXPECT_FALSE(LogContains(kInvalidAddress));
 213  E :  }
 214    :  
 215  E :  TEST_F(AsanRtlTest, AsanReportInvalidAccess) {
 216    :    FARPROC check_access_fn =
 217  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 218  E :    ASSERT_NE(static_cast<FARPROC>(nullptr), check_access_fn);
 219    :  
 220  E :    MemoryAccessorTester tester;
 221  E :    agent::asan::AsanRuntime* runtime = GetActiveRuntimeFunction();
 222  E :    ASSERT_NE(reinterpret_cast<agent::asan::AsanRuntime*>(NULL), runtime);
 223  E :    runtime->params().report_invalid_accesses = true;
 224    :    tester.AssertMemoryErrorIsDetected(
 225  E :        check_access_fn, reinterpret_cast<void*>(0x00000000), INVALID_ADDRESS);
 226  E :    EXPECT_TRUE(LogContains(kInvalidAddress));
 227  E :  }
 228    :  
 229  E :  TEST_F(AsanRtlTest, AsanCheckCorruptBlock) {
 230  E :    void* mem = HeapAllocFunction(heap_, 0, kAllocSize);
 231  E :    reinterpret_cast<uint8*>(mem)[-1]--;
 232  E :    MemoryAccessorTester tester;
 233  E :    tester.set_expected_error_type(CORRUPT_BLOCK);
 234  E :    EXPECT_TRUE(HeapFreeFunction(heap_, 0, mem));
 235  E :    EXPECT_TRUE(tester.memory_error_detected());
 236  E :    EXPECT_TRUE(LogContains(kHeapCorruptBlock));
 237  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 238  E :  }
 239    :  
 240  E :  TEST_F(AsanRtlTest, AsanCheckCorruptHeap) {
 241    :    FARPROC check_access_fn =
 242  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 243  E :    ASSERT_TRUE(check_access_fn != NULL);
 244    :  
 245  E :    agent::asan::AsanRuntime* runtime = GetActiveRuntimeFunction();
 246  E :    ASSERT_NE(reinterpret_cast<agent::asan::AsanRuntime*>(NULL), runtime);
 247  E :    runtime->params().check_heap_on_failure = true;
 248    :  
 249  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
 250  E :    ASSERT_TRUE(mem.get() != NULL);
 251    :  
 252  E :    const size_t kMaxIterations = 10;
 253    :  
 254    :    // Retrieves the information about this block.
 255    :    BlockHeader* header = BlockGetHeaderFromBody(
 256  E :        reinterpret_cast<BlockBody*>(mem.get()));
 257  E :    BlockInfo block_info = {};
 258  E :    EXPECT_TRUE(BlockInfoFromMemory(header, &block_info));
 259    :  
 260    :    // We'll update a non essential value of the block trailer to corrupt it.
 261    :    uint8* mem_in_trailer = reinterpret_cast<uint8*>(
 262  E :        &block_info.trailer->alloc_tid);
 263    :  
 264    :    // This can fail because of a checksum collision. However, we run it a handful
 265    :    // of times to keep the chances as small as possible.
 266  E :    for (size_t i = 0; i < kMaxIterations; ++i) {
 267  E :      (*mem_in_trailer)++;
 268  E :      MemoryAccessorTester tester;
 269    :      tester.AssertMemoryErrorIsDetected(
 270  E :          check_access_fn, mem.get() + kAllocSize, HEAP_BUFFER_OVERFLOW);
 271  E :      EXPECT_TRUE(LogContains("previously allocated here"));
 272  E :      EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 273    :  
 274    :      if (!tester.last_error_info().heap_is_corrupt &&
 275  E :            i + 1 < kMaxIterations)
 276  i :        continue;
 277    :  
 278  E :      EXPECT_TRUE(tester.last_error_info().heap_is_corrupt);
 279    :  
 280  E :      EXPECT_EQ(1, tester.last_error_info().corrupt_range_count);
 281  E :      EXPECT_EQ(1, tester.last_corrupt_ranges().size());
 282  E :      AsanBlockInfoVector blocks_info = tester.last_corrupt_ranges()[0].second;
 283    :  
 284  E :      EXPECT_EQ(1, blocks_info.size());
 285  E :      EXPECT_EQ(kDataIsCorrupt, blocks_info[0].analysis.block_state);
 286  E :      EXPECT_EQ(kAllocSize, blocks_info[0].user_size);
 287  E :      EXPECT_EQ(block_info.header, blocks_info[0].header);
 288  E :      EXPECT_NE(0U, blocks_info[0].alloc_stack_size);
 289  E :      for (size_t j = 0; j < blocks_info[0].alloc_stack_size; ++j)
 290  E :        EXPECT_NE(reinterpret_cast<void*>(NULL), blocks_info[0].alloc_stack[j]);
 291  E :      EXPECT_EQ(0U, blocks_info[0].free_stack_size);
 292    :  
 293    :      // An error should be triggered when we free this block.
 294  E :      tester.set_memory_error_detected(false);
 295  E :      tester.set_expected_error_type(CORRUPT_BLOCK);
 296  E :      mem.reset(NULL);
 297  E :      EXPECT_TRUE(tester.memory_error_detected());
 298    :  
 299  E :      break;
 300  i :    }
 301  E :  }
 302    :  
 303  E :  TEST_F(AsanRtlTest, AsanSingleSpecial1byteInstructionCheckGoodAccess) {
 304    :    static const char* function_names[] = {
 305    :        "asan_check_1_byte_movs_access",
 306    :        "asan_check_1_byte_cmps_access",
 307    :        "asan_check_1_byte_stos_access"
 308    :    };
 309    :  
 310    :    // Allocate memory space.
 311  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint8));
 312  E :    uint8* src = reinterpret_cast<uint8*>(memory_src_);
 313  E :    uint8* dst = reinterpret_cast<uint8*>(memory_dst_);
 314    :  
 315    :    // Validate memory accesses.
 316  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 317    :      FARPROC check_access_fn =
 318  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 319  E :      ASSERT_TRUE(check_access_fn != NULL);
 320    :  
 321  E :      for (int32 i = 0; i < memory_length_; ++i) {
 322  E :        MemoryAccessorTester tester;
 323    :        tester.ExpectSpecialMemoryErrorIsDetected(
 324    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 325    :          false, &dst[i], &src[i], 0xDEADDEAD,
 326  E :          UNKNOWN_BAD_ACCESS);
 327  E :      }
 328  E :    }
 329    :  
 330  E :    FreeMemoryBuffers();
 331  E :  }
 332    :  
 333  E :  TEST_F(AsanRtlTest, AsanSingleSpecial2byteInstructionCheckGoodAccess) {
 334    :    static const char* function_names[] = {
 335    :        "asan_check_2_byte_movs_access",
 336    :        "asan_check_2_byte_cmps_access",
 337    :        "asan_check_2_byte_stos_access"
 338    :    };
 339    :  
 340    :    // Allocate memory space.
 341  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint16));
 342  E :    uint16* src = reinterpret_cast<uint16*>(memory_src_);
 343  E :    uint16* dst = reinterpret_cast<uint16*>(memory_dst_);
 344    :  
 345    :    // Validate memory accesses.
 346  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 347    :      FARPROC check_access_fn =
 348  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 349  E :      ASSERT_TRUE(check_access_fn != NULL);
 350    :  
 351  E :      for (int32 i = 0; i < memory_length_; ++i) {
 352  E :        MemoryAccessorTester tester;
 353    :        tester.ExpectSpecialMemoryErrorIsDetected(
 354    :            check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 355  E :            false, &dst[i], &src[i], 0xDEADDEAD, UNKNOWN_BAD_ACCESS);
 356  E :      }
 357  E :    }
 358    :  
 359  E :    FreeMemoryBuffers();
 360  E :  }
 361    :  
 362  E :  TEST_F(AsanRtlTest, AsanSingleSpecial4byteInstructionCheckGoodAccess) {
 363    :    static const char* function_names[] = {
 364    :        "asan_check_4_byte_movs_access",
 365    :        "asan_check_4_byte_cmps_access",
 366    :        "asan_check_4_byte_stos_access"
 367    :    };
 368    :  
 369    :    // Allocate memory space.
 370  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 371  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 372  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 373    :  
 374    :    // Validate memory accesses.
 375  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 376    :      FARPROC check_access_fn =
 377  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 378  E :      ASSERT_TRUE(check_access_fn != NULL);
 379    :  
 380  E :      for (int32 i = 0; i < memory_length_; ++i) {
 381  E :        MemoryAccessorTester tester;
 382    :        tester.ExpectSpecialMemoryErrorIsDetected(
 383    :            check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 384  E :            false, &dst[i], &src[i], 0xDEADDEAD, UNKNOWN_BAD_ACCESS);
 385  E :      }
 386  E :    }
 387    :  
 388  E :    FreeMemoryBuffers();
 389  E :  }
 390    :  
 391  E :  TEST_F(AsanRtlTest, AsanSingleSpecialInstructionCheckBadAccess) {
 392    :    static const char* function_names[] = {
 393    :        "asan_check_1_byte_movs_access",
 394    :        "asan_check_1_byte_cmps_access",
 395    :        "asan_check_2_byte_movs_access",
 396    :        "asan_check_2_byte_cmps_access",
 397    :        "asan_check_4_byte_movs_access",
 398    :        "asan_check_4_byte_cmps_access"
 399    :    };
 400    :  
 401    :    // Allocate memory space.
 402  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 403  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 404  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 405    :  
 406    :    // Validate memory accesses.
 407  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 408    :      FARPROC check_access_fn =
 409  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 410  E :      ASSERT_TRUE(check_access_fn != NULL);
 411    :  
 412  E :      MemoryAccessorTester tester;
 413    :      tester.ExpectSpecialMemoryErrorIsDetected(
 414    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 415  E :          true, &dst[0], &src[-1], 0xDEADDEAD, HEAP_BUFFER_UNDERFLOW);
 416    :      tester.ExpectSpecialMemoryErrorIsDetected(
 417    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 418  E :          true, &dst[-1], &src[0], 0xDEADDEAD, HEAP_BUFFER_UNDERFLOW);
 419    :  
 420    :      tester.ExpectSpecialMemoryErrorIsDetected(
 421    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 422  E :          true, &dst[0], &src[memory_length_], 0xDEADDEAD, HEAP_BUFFER_OVERFLOW);
 423    :      tester.ExpectSpecialMemoryErrorIsDetected(
 424    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 425  E :          true, &dst[memory_length_], &src[0], 0xDEADDEAD, HEAP_BUFFER_OVERFLOW);
 426  E :    }
 427    :  
 428  E :    FreeMemoryBuffers();
 429  E :  }
 430    :  
 431  E :  TEST_F(AsanRtlTest, AsanSingleStoInstructionCheckBadAccess) {
 432    :    static const char* function_names[] = {
 433    :        "asan_check_1_byte_stos_access",
 434    :        "asan_check_2_byte_stos_access",
 435    :        "asan_check_4_byte_stos_access"
 436    :    };
 437    :  
 438    :    // Allocate memory space.
 439  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 440  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 441  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 442    :  
 443    :    // Validate memory accesses.
 444  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 445    :      FARPROC check_access_fn =
 446  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 447  E :      ASSERT_TRUE(check_access_fn != NULL);
 448    :  
 449  E :      MemoryAccessorTester tester;
 450    :      tester.ExpectSpecialMemoryErrorIsDetected(
 451    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 452  E :          false, &dst[0], &src[-1], 0xDEAD, HEAP_BUFFER_UNDERFLOW);
 453    :      tester.ExpectSpecialMemoryErrorIsDetected(
 454    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 455  E :          true, &dst[-1], &src[0], 0xDEAD, HEAP_BUFFER_UNDERFLOW);
 456    :  
 457    :      tester.ExpectSpecialMemoryErrorIsDetected(
 458    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 459  E :          false, &dst[0], &src[memory_length_], 0xDEADDEAD, HEAP_BUFFER_OVERFLOW);
 460    :      tester.ExpectSpecialMemoryErrorIsDetected(
 461    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 462  E :          true, &dst[memory_length_], &src[0], 0xDEADDEAD, HEAP_BUFFER_OVERFLOW);
 463  E :    }
 464    :  
 465  E :    FreeMemoryBuffers();
 466  E :  }
 467    :  
 468  E :  TEST_F(AsanRtlTest, AsanPrefixedSpecialInstructionCheckGoodAccess) {
 469    :    static const char* function_names[] = {
 470    :        "asan_check_repz_4_byte_movs_access",
 471    :        "asan_check_repz_4_byte_cmps_access",
 472    :        "asan_check_repz_4_byte_stos_access"
 473    :    };
 474    :  
 475    :    // Allocate memory space.
 476  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 477  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 478  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 479    :  
 480    :    // Validate memory accesses.
 481  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 482    :      FARPROC check_access_fn =
 483  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 484  E :      ASSERT_TRUE(check_access_fn != NULL);
 485    :  
 486  E :      MemoryAccessorTester tester;
 487    :      tester.ExpectSpecialMemoryErrorIsDetected(
 488    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 489  E :          false, &dst[0], &src[0], memory_length_, UNKNOWN_BAD_ACCESS);
 490  E :    }
 491    :  
 492  E :    FreeMemoryBuffers();
 493  E :  }
 494    :  
 495  E :  TEST_F(AsanRtlTest, AsanPrefixedSpecialInstructionCheckBadAccess) {
 496    :    static const char* function_names[] = {
 497    :        "asan_check_repz_4_byte_movs_access",
 498    :        "asan_check_repz_4_byte_cmps_access",
 499    :        "asan_check_repz_4_byte_stos_access"
 500    :    };
 501    :  
 502    :    // Allocate memory space.
 503  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 504  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 505  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 506    :  
 507    :    // Validate memory accesses.
 508  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 509    :      FARPROC check_access_fn =
 510  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 511  E :      ASSERT_TRUE(check_access_fn != NULL);
 512    :  
 513  E :      MemoryAccessorTester tester;
 514    :      tester.ExpectSpecialMemoryErrorIsDetected(
 515    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 516  E :          true, &dst[0], &src[0], memory_length_ + 1, HEAP_BUFFER_OVERFLOW);
 517    :      tester.ExpectSpecialMemoryErrorIsDetected(
 518    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 519  E :          true, &dst[-1], &src[-1], memory_length_, HEAP_BUFFER_UNDERFLOW);
 520    :      tester.ExpectSpecialMemoryErrorIsDetected(
 521    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 522  E :          true, &dst[-1], &src[0], memory_length_, HEAP_BUFFER_UNDERFLOW);
 523  E :    }
 524    :  
 525  E :    FreeMemoryBuffers();
 526  E :  }
 527    :  
 528  E :  TEST_F(AsanRtlTest, AsanDirectionSpecialInstructionCheckGoodAccess) {
 529    :    static const char* function_names[] = {
 530    :        "asan_check_repz_4_byte_movs_access",
 531    :        "asan_check_repz_4_byte_cmps_access",
 532    :        "asan_check_repz_4_byte_stos_access"
 533    :    };
 534    :  
 535    :    // Allocate memory space.
 536  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 537  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 538  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 539    :  
 540    :    // Validate memory accesses.
 541  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 542    :      FARPROC check_access_fn =
 543  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 544  E :      ASSERT_TRUE(check_access_fn != NULL);
 545    :  
 546  E :      MemoryAccessorTester tester;
 547    :      tester.ExpectSpecialMemoryErrorIsDetected(
 548    :          check_access_fn, MemoryAccessorTester::DIRECTION_BACKWARD,
 549    :          false, &dst[memory_length_ - 1],
 550    :          &src[memory_length_ - 1], memory_length_,
 551  E :          UNKNOWN_BAD_ACCESS);
 552  E :    }
 553    :  
 554  E :    FreeMemoryBuffers();
 555  E :  }
 556    :  
 557  E :  TEST_F(AsanRtlTest, AsanSpecialInstructionCheckZeroAccess) {
 558    :    static const char* function_names[] = {
 559    :        "asan_check_repz_1_byte_movs_access",
 560    :        "asan_check_repz_1_byte_cmps_access",
 561    :        "asan_check_repz_1_byte_stos_access",
 562    :        "asan_check_repz_2_byte_movs_access",
 563    :        "asan_check_repz_2_byte_cmps_access",
 564    :        "asan_check_repz_2_byte_stos_access",
 565    :        "asan_check_repz_4_byte_movs_access",
 566    :        "asan_check_repz_4_byte_cmps_access",
 567    :        "asan_check_repz_4_byte_stos_access"
 568    :    };
 569    :  
 570    :    // Allocate memory space.
 571  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 572  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 573  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 574    :  
 575    :    // Validate memory accesses.
 576  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 577    :      FARPROC check_access_fn =
 578  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 579  E :      ASSERT_TRUE(check_access_fn != NULL);
 580    :  
 581    :      // A prefixed instruction with a count of zero do not have side effects.
 582  E :      MemoryAccessorTester tester;
 583    :      tester.ExpectSpecialMemoryErrorIsDetected(
 584    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 585  E :          false, &dst[-1], &src[-1], 0, UNKNOWN_BAD_ACCESS);
 586  E :    }
 587    :  
 588  E :    FreeMemoryBuffers();
 589  E :  }
 590    :  
 591  E :  TEST_F(AsanRtlTest, AsanSpecialInstructionCheckShortcutAccess) {
 592    :    static const char* function_names[] = {
 593    :        "asan_check_repz_1_byte_cmps_access",
 594    :        "asan_check_repz_2_byte_cmps_access",
 595    :        "asan_check_repz_4_byte_cmps_access",
 596    :    };
 597    :  
 598    :    // Allocate memory space.
 599  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 600  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 601  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 602    :  
 603  E :    src[1] = 0x12345667;
 604    :  
 605    :    // Validate memory accesses.
 606  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 607    :      FARPROC check_access_fn =
 608  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 609  E :      ASSERT_TRUE(check_access_fn != NULL);
 610    :  
 611    :      // Compare instruction stop their execution when values differ.
 612  E :      MemoryAccessorTester tester;
 613    :      tester.ExpectSpecialMemoryErrorIsDetected(
 614    :          check_access_fn, MemoryAccessorTester::DIRECTION_FORWARD,
 615  E :          false, &dst[0], &src[0], memory_length_ + 1, UNKNOWN_BAD_ACCESS);
 616  E :    }
 617    :  
 618  E :    FreeMemoryBuffers();
 619  E :  }
 620    :  
 621  E :  TEST_F(AsanRtlTest, AllocationFilterFlag) {
 622  E :    agent::asan::AsanRuntime* runtime = GetActiveRuntimeFunction();
 623  E :    SetAllocationFilterFlagFunction();
 624  E :    EXPECT_TRUE(runtime->allocation_filter_flag());
 625  E :    ClearAllocationFilterFlagFunction();
 626  E :    EXPECT_FALSE(runtime->allocation_filter_flag());
 627  E :    SetAllocationFilterFlagFunction();
 628  E :    EXPECT_TRUE(runtime->allocation_filter_flag());
 629  E :  }
 630    :  
 631    :  }  // namespace asan
 632    :  }  // namespace agent

Coverage information generated Thu Jan 14 17:40:38 2016.