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

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

Coverage information generated Thu Mar 26 16:15:41 2015.