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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
96.3%9629990.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 "base/bind.h"
  18    :  #include "base/file_util.h"
  19    :  #include "base/synchronization/waitable_event.h"
  20    :  #include "base/threading/thread.h"
  21    :  #include "base/win/scoped_handle.h"
  22    :  #include "gtest/gtest.h"
  23    :  #include "syzygy/agent/asan/asan_heap.h"
  24    :  #include "syzygy/agent/asan/asan_rtl_impl.h"
  25    :  #include "syzygy/agent/asan/asan_runtime.h"
  26    :  #include "syzygy/agent/asan/asan_shadow.h"
  27    :  #include "syzygy/agent/asan/unittest_util.h"
  28    :  #include "syzygy/core/unittest_util.h"
  29    :  
  30    :  namespace agent {
  31    :  namespace asan {
  32    :  
  33    :  namespace {
  34    :  
  35    :  // The access check function invoked by the below.
  36    :  FARPROC check_access_fn = NULL;
  37    :  // A flag used in asan callback to ensure that a memory error has been detected.
  38    :  bool memory_error_detected = false;
  39    :  // A pointer to a context to ensure that we're able to restore the context when
  40    :  // an asan error is found.
  41    :  CONTEXT* context_before_hook = NULL;
  42    :  // This will be used in the asan callback to ensure that we detect the right
  43    :  // error.
  44    :  HeapProxy::BadAccessKind expected_error_type = HeapProxy::UNKNOWN_BAD_ACCESS;
  45    :  // A flag to override the direction flag on special instruction checker.
  46    :  bool direction_flag_forward = true;
  47    :  // An arbitrary size for the buffer we allocate in the different unittests.
  48    :  const size_t kAllocSize = 13;
  49    :  
  50    :  // Shorthand for discussing all the asan runtime functions.
  51    :  #define ASAN_RTL_FUNCTIONS(F)  \
  52    :      F(WINAPI, HANDLE, HeapCreate,  \
  53    :        (DWORD options, SIZE_T initial_size, SIZE_T maximum_size))  \
  54    :      F(WINAPI, BOOL, HeapDestroy,  \
  55    :        (HANDLE heap))  \
  56    :      F(WINAPI, LPVOID, HeapAlloc,  \
  57    :        (HANDLE heap, DWORD flags, SIZE_T bytes))  \
  58    :      F(WINAPI, LPVOID, HeapReAlloc,  \
  59    :        (HANDLE heap, DWORD flags, LPVOID mem, SIZE_T bytes))  \
  60    :      F(WINAPI, BOOL, HeapFree,  \
  61    :        (HANDLE heap, DWORD flags, LPVOID mem))  \
  62    :      F(WINAPI, SIZE_T, HeapSize,  \
  63    :        (HANDLE heap, DWORD flags, LPCVOID mem))  \
  64    :      F(WINAPI, BOOL, HeapValidate,  \
  65    :        (HANDLE heap, DWORD flags, LPCVOID mem))  \
  66    :      F(WINAPI, SIZE_T, HeapCompact,  \
  67    :        (HANDLE heap, DWORD flags))  \
  68    :      F(WINAPI, BOOL, HeapLock, (HANDLE heap))  \
  69    :      F(WINAPI, BOOL, HeapUnlock, (HANDLE heap))  \
  70    :      F(WINAPI, BOOL, HeapWalk,  \
  71    :        (HANDLE heap, LPPROCESS_HEAP_ENTRY entry))  \
  72    :      F(WINAPI, BOOL, HeapSetInformation,  \
  73    :        (HANDLE heap, HEAP_INFORMATION_CLASS info_class,  \
  74    :         PVOID info, SIZE_T info_length))  \
  75    :      F(WINAPI, BOOL, HeapQueryInformation,  \
  76    :        (HANDLE heap, HEAP_INFORMATION_CLASS info_class,  \
  77    :         PVOID info, SIZE_T info_length, PSIZE_T return_length))  \
  78    :      F(WINAPI, void, SetCallBack,  \
  79    :        (void (*callback)(AsanErrorInfo* error_info)))  \
  80    :      F(_cdecl, void*, memcpy,  \
  81    :        (void* destination, const void* source,  size_t num))  \
  82    :      F(_cdecl, void*, memmove,  \
  83    :        (void* destination, const void* source, size_t num))  \
  84    :      F(_cdecl, void*, memset, (void* ptr, int value, size_t num))  \
  85    :      F(_cdecl, const void*, memchr, (const void* ptr, int value, size_t num))  \
  86    :      F(_cdecl, size_t, strcspn, (const char* str1, const char* str2))  \
  87    :      F(_cdecl, size_t, strlen, (const char* str))  \
  88    :      F(_cdecl, const char*, strrchr, (const char* str, int character))  \
  89    :      F(_cdecl, int, strcmp, (const char* str1, const char* str2))  \
  90    :      F(_cdecl, const char*, strpbrk, (const char* str1, const char* str2))  \
  91    :      F(_cdecl, const char*, strstr, (const char* str1, const char* str2))  \
  92    :      F(_cdecl, size_t, strspn, (const char* str1, const char* str2))  \
  93    :      F(_cdecl, char*, strncpy,  \
  94    :        (char* destination, const char* source, size_t num))  \
  95    :      F(_cdecl, char*, strncat,  \
  96    :        (char* destination, const char* source, size_t num))  \
  97    :      F(_cdecl, void, PoisonMemoryRange, (const void* address, size_t size))  \
  98    :      F(_cdecl, void, UnpoisonMemoryRange, (const void* address, size_t size))  \
  99    :      F(_cdecl, void, GetAsanObjectSize,  \
 100    :        (size_t user_object_size, size_t alignment))  \
 101    :      F(_cdecl, void, InitializeObject,  \
 102    :        (void* asan_pointer, size_t user_object_size, size_t alignment))  \
 103    :      F(_cdecl, void, GetUserExtent,  \
 104    :        (const void* asan_pointer, void** user_pointer, size_t* size))  \
 105    :      F(_cdecl, void, GetAsanExtent,  \
 106    :        (const void* user_pointer, void** asan_pointer, size_t* size))  \
 107    :      F(_cdecl, void, QuarantineObject, (void* asan_pointer))  \
 108    :      F(_cdecl, void, DestroyObject, (void* asan_pointer))  \
 109    :      F(_cdecl, void, CloneObject,  \
 110    :        (const void* src_asan_pointer, const void* dst_asan_pointer))  \
 111    :      F(WINAPI, BOOL, ReadFile,  \
 112    :        (HANDLE file_handle, LPVOID buffer, DWORD bytes_to_read,  \
 113    :         LPDWORD bytes_read, LPOVERLAPPED overlapped))  \
 114    :      F(WINAPI, BOOL, WriteFile,  \
 115    :        (HANDLE file_handle, LPCVOID buffer, DWORD bytes_to_write,  \
 116    :         LPDWORD bytes_written, LPOVERLAPPED overlapped))  \
 117    :      F(_cdecl, void, SetInterceptorCallback, (void (*callback)()))
 118    :  
 119    :  #define DECLARE_ASAN_FUNCTION_PTR(convention, ret, name, args) \
 120    :    typedef ret (convention* name##FunctionPtr)args;
 121    :  
 122    :  ASAN_RTL_FUNCTIONS(DECLARE_ASAN_FUNCTION_PTR)
 123    :  
 124    :  #undef DECLARE_ASAN_FUNCTION_PTR
 125    :  
 126    :  class AsanRtlTest : public testing::TestWithAsanLogger {
 127    :   public:
 128    :    AsanRtlTest() : asan_rtl_(NULL), heap_(NULL),
 129    :      memory_src_(NULL), memory_dst_(NULL),
 130  E :      memory_length_(0), memory_size_(0) {
 131  E :    }
 132    :  
 133  E :    void SetUp() OVERRIDE {
 134  E :      testing::TestWithAsanLogger::SetUp();
 135  E :      memory_error_detected = false;
 136    :  
 137    :      // Load the ASAN runtime library.
 138    :      base::FilePath asan_rtl_path =
 139  E :          testing::GetExeRelativePath(L"syzyasan_rtl.dll");
 140  E :      asan_rtl_ = ::LoadLibrary(asan_rtl_path.value().c_str());
 141  E :      ASSERT_TRUE(asan_rtl_ != NULL);
 142    :  
 143    :      // Load all the functions and assert that we find them.
 144    :  #define LOAD_ASAN_FUNCTION(convention, ret, name, args)  \
 145    :      name##Function = reinterpret_cast<name##FunctionPtr>(  \
 146    :          ::GetProcAddress(asan_rtl_, "asan_" #name));  \
 147    :      ASSERT_TRUE(name##Function != NULL);
 148    :  
 149  E :      ASAN_RTL_FUNCTIONS(LOAD_ASAN_FUNCTION)
 150    :  
 151    :  #undef LOAD_ASAN_FUNCTION
 152    :  
 153  E :      heap_ = HeapCreateFunction(0, 0, 0);
 154  E :      ASSERT_TRUE(heap_ != NULL);
 155  E :    }
 156    :  
 157  E :    void TearDown() OVERRIDE {
 158  E :      if (heap_ != NULL) {
 159  E :        HeapDestroyFunction(heap_);
 160  E :        heap_ = NULL;
 161    :      }
 162    :  
 163  E :      if (asan_rtl_ != NULL) {
 164  E :        ::FreeLibrary(asan_rtl_);
 165  E :        asan_rtl_ = NULL;
 166    :      }
 167    :  
 168  E :      testing::TestWithAsanLogger::TearDown();
 169  E :    }
 170    :  
 171  E :    HANDLE heap() { return heap_; }
 172    :  
 173    :    // Declare the function pointers.
 174    :  #define DECLARE_FUNCTION_PTR_VARIABLE(convention, ret, name, args)  \
 175    :      static name##FunctionPtr AsanRtlTest::name##Function;
 176    :  
 177    :    ASAN_RTL_FUNCTIONS(DECLARE_FUNCTION_PTR_VARIABLE)
 178    :  
 179    :  #undef DECLARE_FUNCTION_PTR_VARIABLE
 180    :  
 181    :   protected:
 182    :    void AllocMemoryBuffers(int32 length, int32 element_size);
 183    :    void FreeMemoryBuffers();
 184    :  
 185    :    // The ASAN runtime module to test.
 186    :    HMODULE asan_rtl_;
 187    :  
 188    :    // Scratch heap handle valid from SetUp to TearDown.
 189    :    HANDLE heap_;
 190    :  
 191    :    // Memory buffers used to test special instructions.
 192    :    void* memory_src_;
 193    :    void* memory_dst_;
 194    :    int32 memory_length_;
 195    :    int32 memory_size_;
 196    :  };
 197    :  
 198    :  // A helper struct to be passed as a destructor of ASan scoped allocation.
 199    :  struct ASanDeleteHelper {
 200  E :    explicit ASanDeleteHelper(AsanRtlTest* asan_rtl)
 201    :        : asan_rtl_(asan_rtl) {
 202  E :    }
 203    :  
 204  E :    void operator()(void* ptr) {
 205  E :      asan_rtl_->HeapFreeFunction(asan_rtl_->heap(), 0, ptr);
 206  E :    }
 207    :    AsanRtlTest* asan_rtl_;
 208    :  };
 209    :  
 210    :  // A scoped_ptr specialization for the ASan allocations.
 211    :  template <typename T>
 212    :  class ScopedASanAlloc : public scoped_ptr<T, ASanDeleteHelper> {
 213    :   public:
 214    :    explicit ScopedASanAlloc(AsanRtlTest* asan_rtl)
 215    :        : scoped_ptr(NULL, ASanDeleteHelper(asan_rtl)) {
 216    :    }
 217    :  
 218  E :    ScopedASanAlloc(AsanRtlTest* asan_rtl, size_t size)
 219    :        : scoped_ptr(NULL, ASanDeleteHelper(asan_rtl)) {
 220  E :      Allocate(asan_rtl, size);
 221  E :    }
 222    :  
 223    :    template <typename T2>
 224  E :    T2* GetAs() {
 225  E :      return reinterpret_cast<T2*>(get());
 226  E :    }
 227    :  
 228  E :    void Allocate(AsanRtlTest* asan_rtl, size_t size) {
 229  E :      ASSERT_TRUE(asan_rtl != NULL);
 230    :      reset(reinterpret_cast<T*>(
 231  E :          asan_rtl->HeapAllocFunction(asan_rtl->heap(), 0, size * sizeof(T))));
 232  E :      memset(get(), 0, size * sizeof(T));
 233  E :    }
 234    :  
 235    :    T operator[](int i) const {
 236    :      CHECK(get() != NULL);
 237    :      return get()[i];
 238    :    }
 239    :  
 240  E :    T& operator[](int i) {
 241  E :      CHECK(get() != NULL);
 242  E :      return get()[i];
 243  E :    }
 244    :  };
 245    :  
 246    :  // Define the function pointers.
 247    :  #define DEFINE_FUNCTION_PTR_VARIABLE(convention, ret, name, args)  \
 248    :      name##FunctionPtr AsanRtlTest::name##Function;
 249    :  
 250    :    ASAN_RTL_FUNCTIONS(DEFINE_FUNCTION_PTR_VARIABLE)
 251    :  
 252    :  #undef DEFINE_FUNCTION_PTR_VARIABLE
 253    :  
 254    :  #define RTL_CAPTURE_CONTEXT(context, expected_eip) {  \
 255    :    /* Save caller save registers. */  \
 256    :    __asm push eax  \
 257    :    __asm push ecx  \
 258    :    __asm push edx  \
 259    :    /* Call Capture context. */  \
 260    :    __asm push context  \
 261    :    __asm call dword ptr[RtlCaptureContext]  \
 262    :    /* Restore caller save registers. */  \
 263    :    __asm pop edx  \
 264    :    __asm pop ecx  \
 265    :    __asm pop eax  \
 266    :    /* Restore registers which are stomped by RtlCaptureContext. */  \
 267    :    __asm push eax  \
 268    :    __asm pushfd  \
 269    :    __asm mov eax, context  \
 270    :    __asm mov dword ptr[eax + CONTEXT.Ebp], ebp  \
 271    :    __asm mov dword ptr[eax + CONTEXT.Esp], esp  \
 272    :    /* NOTE: we need to add 8 bytes because EAX + EFLAGS are on the stack. */  \
 273    :    __asm add dword ptr[eax + CONTEXT.Esp], 8  \
 274    :    __asm mov dword ptr[eax + CONTEXT.Eip], offset expected_eip  \
 275    :    __asm popfd  \
 276    :    __asm pop eax  \
 277    :  }
 278    :  
 279    :  // Check if the sections of 2 context are equals.
 280    :  // @param c1 The first context to check.
 281    :  // @param c2 The second context to check.
 282    :  // @param flags The sections to compare.
 283  E :  void ExpectEqualContexts(const CONTEXT& c1, const CONTEXT& c2, DWORD flags) {
 284  E :    if ((flags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
 285  E :      EXPECT_EQ(c1.SegGs, c2.SegGs);
 286  E :      EXPECT_EQ(c1.SegFs, c2.SegFs);
 287  E :      EXPECT_EQ(c1.SegEs, c2.SegEs);
 288  E :      EXPECT_EQ(c1.SegDs, c2.SegDs);
 289    :    }
 290    :  
 291  E :    if ((flags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
 292  E :      EXPECT_EQ(c1.Edi, c2.Edi);
 293  E :      EXPECT_EQ(c1.Esi, c2.Esi);
 294  E :      EXPECT_EQ(c1.Ebx, c2.Ebx);
 295  E :      EXPECT_EQ(c1.Edx, c2.Edx);
 296  E :      EXPECT_EQ(c1.Ecx, c2.Ecx);
 297  E :      EXPECT_EQ(c1.Eax, c2.Eax);
 298    :    }
 299    :  
 300  E :    if ((flags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
 301  E :      EXPECT_EQ(c1.Ebp, c2.Ebp);
 302  E :      EXPECT_EQ(c1.Eip, c2.Eip);
 303  E :      EXPECT_EQ(c1.SegCs, c2.SegCs);
 304  E :      EXPECT_EQ(c1.EFlags, c2.EFlags);
 305  E :      EXPECT_EQ(c1.Esp, c2.Esp);
 306  E :      EXPECT_EQ(c1.SegSs, c2.SegSs);
 307    :    }
 308  E :  }
 309    :  
 310    :  void CheckAccessAndCaptureContexts(
 311  i :      CONTEXT* before, CONTEXT* after, void* location) {
 312    :    __asm {
 313  i :      pushad
 314  i :      pushfd
 315    :  
 316    :      // Avoid undefined behavior by forcing values.
 317  i :      mov eax, 0x01234567
 318  i :      mov ebx, 0x70123456
 319  i :      mov ecx, 0x12345678
 320  i :      mov edx, 0x56701234
 321  i :      mov esi, 0xCCAACCAA
 322  i :      mov edi, 0xAACCAACC
 323    :  
 324  i :      RTL_CAPTURE_CONTEXT(before, check_access_expected_eip)
 325    :  
 326    :      // Push EDX as we're required to do by the custom calling convention.
 327  i :      push edx
 328    :      // Ptr is the pointer to check.
 329  i :      mov edx, location
 330    :      // Call through.
 331  i :      call dword ptr[check_access_fn + 0]
 332    :   check_access_expected_eip:
 333    :  
 334  i :      RTL_CAPTURE_CONTEXT(after, check_access_expected_eip)
 335    :  
 336  i :      popfd
 337  i :      popad
 338    :    }
 339  i :  }
 340    :  
 341  E :  void CheckAccessAndCompareContexts(void* ptr) {
 342  E :    CONTEXT before = {};
 343  E :    CONTEXT after = {};
 344    :  
 345  E :    context_before_hook = &before;
 346  E :    CheckAccessAndCaptureContexts(&before, &after, ptr);
 347    :  
 348  E :    ExpectEqualContexts(before, after, CONTEXT_FULL);
 349    :  
 350  E :    context_before_hook = NULL;
 351  E :  }
 352    :  
 353    :  void CheckSpecialAccess(CONTEXT* before, CONTEXT* after,
 354  i :                          void* dst, void* src, int len) {
 355    :    __asm {
 356  i :      pushad
 357  i :      pushfd
 358    :  
 359    :      // Override the direction flag.
 360  i :      cld
 361  i :      cmp direction_flag_forward, 0
 362  i :      jne skip_reverse_direction
 363  i :      std
 364    :   skip_reverse_direction:
 365    :  
 366    :      // Avoid undefined behavior by forcing values.
 367  i :      mov eax, 0x01234567
 368  i :      mov ebx, 0x70123456
 369  i :      mov edx, 0x56701234
 370    :  
 371    :      // Setup registers used by the special instruction.
 372  i :      mov ecx, len
 373  i :      mov esi, src
 374  i :      mov edi, dst
 375    :  
 376  i :      RTL_CAPTURE_CONTEXT(before, special_access_expected_eip)
 377    :  
 378    :      // Call through.
 379  i :      call dword ptr[check_access_fn + 0]
 380    :   special_access_expected_eip:
 381    :  
 382  i :      RTL_CAPTURE_CONTEXT(after, special_access_expected_eip)
 383    :  
 384  i :      popfd
 385  i :      popad
 386    :    }
 387  i :  }
 388    :  
 389  E :  void CheckSpecialAccessAndCompareContexts(void* dst, void* src, int len) {
 390  E :    CONTEXT before = {};
 391  E :    CONTEXT after = {};
 392    :  
 393  E :    context_before_hook = &before;
 394    :  
 395  E :    CheckSpecialAccess(&before, &after, dst, src, len);
 396    :  
 397  E :    ExpectEqualContexts(before, after, CONTEXT_FULL);
 398    :  
 399  E :    context_before_hook = NULL;
 400  E :  }
 401    :  
 402  E :  void AsanErrorCallback(AsanErrorInfo* error_info) {
 403    :    // TODO(sebmarchand): Stash the error info in a fixture-static variable and
 404    :    // assert on specific conditions after the fact.
 405  E :    EXPECT_TRUE(context_before_hook != NULL);
 406  E :    EXPECT_NE(HeapProxy::UNKNOWN_BAD_ACCESS, error_info->error_type);
 407    :  
 408  E :    EXPECT_EQ(expected_error_type, error_info->error_type);
 409  E :    if (error_info->error_type >= HeapProxy::USE_AFTER_FREE) {
 410    :      // We should at least have the stack trace of the allocation of this block.
 411  E :      EXPECT_GT(error_info->alloc_stack_size, 0U);
 412  E :      EXPECT_NE(0U, error_info->alloc_tid);
 413  E :      if (error_info->error_type == HeapProxy::USE_AFTER_FREE) {
 414  E :        EXPECT_GT(error_info->free_stack_size, 0U);
 415  E :        EXPECT_NE(0U, error_info->free_tid);
 416  E :      } else {
 417  E :        EXPECT_EQ(error_info->free_stack_size, 0U);
 418  E :        EXPECT_EQ(0U, error_info->free_tid);
 419    :      }
 420    :    }
 421    :  
 422  E :    if (error_info->error_type == HeapProxy::HEAP_BUFFER_OVERFLOW) {
 423  E :      EXPECT_TRUE(strstr(error_info->shadow_info, "beyond") != NULL);
 424  E :    } else if (error_info->error_type == HeapProxy::HEAP_BUFFER_UNDERFLOW) {
 425  E :      EXPECT_TRUE(strstr(error_info->shadow_info, "before") != NULL);
 426    :    }
 427    :  
 428  E :    memory_error_detected = true;
 429    :    ExpectEqualContexts(*context_before_hook,
 430    :                        error_info->context,
 431  E :                        CONTEXT_INTEGER | CONTEXT_CONTROL);
 432  E :  }
 433    :  
 434  E :  void AsanErrorCallbackWithoutComparingContext(AsanErrorInfo* error_info) {
 435  E :    memory_error_detected = true;
 436  E :  }
 437    :  
 438    :  void AssertMemoryErrorIsDetected(void* ptr,
 439  E :                                   HeapProxy::BadAccessKind bad_access_type) {
 440  E :    expected_error_type = bad_access_type;
 441  E :    memory_error_detected = false;
 442  E :    CheckAccessAndCompareContexts(ptr);
 443  E :    ASSERT_TRUE(memory_error_detected);
 444  E :  }
 445    :  
 446    :  void ExpectSpecialMemoryErrorIsDetected(bool expected,
 447    :      void* dst, void* src, int32 length,
 448  E :      HeapProxy::BadAccessKind bad_access_type) {
 449  E :    DCHECK(dst != NULL);
 450  E :    DCHECK(src != NULL);
 451  E :    ASSERT_TRUE(check_access_fn != NULL);
 452  E :    expected_error_type = bad_access_type;
 453    :  
 454    :    // Setup the callback to detect invalid accesses.
 455  E :    memory_error_detected = false;
 456    :  
 457    :    // Perform memory accesses inside the range.
 458    :    ASSERT_NO_FATAL_FAILURE(
 459  E :        CheckSpecialAccessAndCompareContexts(dst, src, length));
 460    :  
 461  E :    EXPECT_EQ(expected, memory_error_detected);
 462  E :  }
 463    :  
 464    :  }  // namespace
 465    :  
 466  E :  TEST_F(AsanRtlTest, AsanCheckGoodAccess) {
 467    :    check_access_fn =
 468  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 469  E :    ASSERT_TRUE(check_access_fn != NULL);
 470    :  
 471    :    // Run through access checking an allocation that's larger than our
 472    :    // block size (8), but not a multiple thereof to exercise all paths
 473    :    // in the access check function (save for the failure path).
 474  E :    ScopedASanAlloc<uint8> mem(this, kAllocSize);
 475  E :    ASSERT_TRUE(mem.get() != NULL);
 476    :  
 477  E :    for (size_t i = 0; i < kAllocSize; ++i) {
 478  E :      ASSERT_NO_FATAL_FAILURE(CheckAccessAndCompareContexts(mem.get() + i));
 479  E :    }
 480  E :  }
 481    :  
 482  E :  TEST_F(AsanRtlTest, AsanCheckHeapBufferOverflow) {
 483    :    check_access_fn =
 484  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 485  E :    ASSERT_TRUE(check_access_fn != NULL);
 486    :  
 487  E :    ScopedASanAlloc<uint8> mem(this, kAllocSize);
 488  E :    ASSERT_TRUE(mem.get() != NULL);
 489    :  
 490  E :    SetCallBackFunction(&AsanErrorCallback);
 491    :    AssertMemoryErrorIsDetected(mem.get() + kAllocSize,
 492  E :                                HeapProxy::HEAP_BUFFER_OVERFLOW);
 493  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 494  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
 495  E :  }
 496    :  
 497  E :  TEST_F(AsanRtlTest, AsanCheckHeapBufferUnderflow) {
 498    :    check_access_fn =
 499  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 500  E :    ASSERT_TRUE(check_access_fn != NULL);
 501    :  
 502  E :    const size_t kAllocSize = 13;
 503  E :    ScopedASanAlloc<uint8> mem(this, kAllocSize);
 504  E :    ASSERT_TRUE(mem.get() != NULL);
 505    :  
 506  E :    SetCallBackFunction(&AsanErrorCallback);
 507  E :    AssertMemoryErrorIsDetected(mem.get() - 1, HeapProxy::HEAP_BUFFER_UNDERFLOW);
 508  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 509  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
 510  E :  }
 511    :  
 512  E :  TEST_F(AsanRtlTest, AsanCheckUseAfterFree) {
 513    :    check_access_fn =
 514  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 515  E :    ASSERT_TRUE(check_access_fn != NULL);
 516    :  
 517  E :    const size_t kAllocSize = 13;
 518  E :    ScopedASanAlloc<uint8> mem(this, kAllocSize);
 519  E :    ASSERT_TRUE(mem.get() != NULL);
 520    :  
 521  E :    SetCallBackFunction(&AsanErrorCallback);
 522  E :    uint8* mem_ptr = mem.get();
 523  E :    mem.reset(NULL);
 524  E :    AssertMemoryErrorIsDetected(mem_ptr, HeapProxy::USE_AFTER_FREE);
 525  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 526  E :    EXPECT_TRUE(LogContains("freed here"));
 527  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
 528  E :  }
 529    :  
 530  E :  TEST_F(AsanRtlTest, AsanCheckDoubleFree) {
 531    :    check_access_fn =
 532  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 533  E :    ASSERT_TRUE(check_access_fn != NULL);
 534    :  
 535  E :    const size_t kAllocSize = 13;
 536  E :    uint8* mem_ptr = NULL;
 537    :    {
 538  E :      ScopedASanAlloc<uint8> mem(this, kAllocSize);
 539  E :      ASSERT_TRUE(mem.get() != NULL);
 540  E :      mem_ptr = mem.get();
 541  E :    }
 542    :  
 543  E :    CONTEXT context_before_error = {};
 544  E :    context_before_hook = &context_before_error;
 545  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
 546  E :    EXPECT_FALSE(HeapFreeFunction(heap_, 0, mem_ptr));
 547  E :    EXPECT_TRUE(memory_error_detected);
 548  E :    EXPECT_TRUE(LogContains(HeapProxy::kAttemptingDoubleFree));
 549  E :    EXPECT_TRUE(LogContains("previously allocated here"));
 550  E :    EXPECT_TRUE(LogContains("freed here"));
 551  E :  }
 552    :  
 553  E :  TEST_F(AsanRtlTest, AsanCheckWildAccess) {
 554    :    check_access_fn =
 555  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 556  E :    ASSERT_TRUE(check_access_fn != NULL);
 557    :  
 558  E :    SetCallBackFunction(&AsanErrorCallback);
 559    :    AssertMemoryErrorIsDetected(reinterpret_cast<void*>(0x80000000),
 560  E :                                HeapProxy::WILD_ACCESS);
 561  E :    EXPECT_TRUE(LogContains(HeapProxy::kWildAccess));
 562  E :  }
 563    :  
 564  E :  TEST_F(AsanRtlTest, AsanCheckInvalidAccess) {
 565    :    check_access_fn =
 566  E :        ::GetProcAddress(asan_rtl_, "asan_check_4_byte_read_access");
 567  E :    ASSERT_TRUE(check_access_fn != NULL);
 568    :  
 569  E :    SetCallBackFunction(&AsanErrorCallback);
 570    :    AssertMemoryErrorIsDetected(reinterpret_cast<void*>(0x00000000),
 571  E :                                HeapProxy::INVALID_ADDRESS);
 572  E :    EXPECT_TRUE(LogContains(HeapProxy::kInvalidAddress));
 573  E :  }
 574    :  
 575  E :  void AsanRtlTest::AllocMemoryBuffers(int32 length, int32 element_size) {
 576  E :    DCHECK(memory_src_ == NULL);
 577  E :    DCHECK(memory_dst_ == NULL);
 578  E :    DCHECK_EQ(0, memory_length_);
 579  E :    DCHECK_EQ(0, memory_size_);
 580    :  
 581    :    // Keep track of memory size.
 582  E :    memory_length_ = length;
 583  E :    memory_size_ = length * element_size;
 584    :  
 585    :    // Allocate memory space.
 586  E :    memory_src_ = HeapAllocFunction(heap_, 0, memory_size_);
 587  E :    ASSERT_TRUE(memory_src_ != NULL);
 588  E :    memory_dst_ = HeapAllocFunction(heap_, 0, memory_size_);
 589  E :    ASSERT_TRUE(memory_dst_ != NULL);
 590    :  
 591    :    // Initialize memory.
 592  E :    memset(memory_src_, 0, memory_size_);
 593  E :    memset(memory_dst_, 0, memory_size_);
 594  E :  }
 595    :  
 596  E :  void AsanRtlTest::FreeMemoryBuffers() {
 597  E :    DCHECK(memory_src_ != NULL);
 598  E :    DCHECK(memory_dst_ != NULL);
 599    :  
 600  E :    ASSERT_TRUE(HeapFreeFunction(heap_, 0, memory_src_));
 601  E :    ASSERT_TRUE(HeapFreeFunction(heap_, 0, memory_dst_));
 602    :  
 603  E :    memory_length_ = 0;
 604  E :    memory_size_ = 0;
 605  E :    memory_src_ = NULL;
 606  E :    memory_dst_ = NULL;
 607  E :  }
 608    :  
 609  E :  TEST_F(AsanRtlTest, AsanSingleSpecial1byteInstructionCheckGoodAccess) {
 610    :    static const char* function_names[] = {
 611    :        "asan_check_1_byte_movs_access",
 612    :        "asan_check_1_byte_cmps_access",
 613    :        "asan_check_1_byte_stos_access"
 614    :    };
 615    :  
 616    :    // Setup the callback to detect invalid accesses.
 617  E :    SetCallBackFunction(&AsanErrorCallback);
 618    :  
 619    :    // Allocate memory space.
 620  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint8));
 621  E :    uint8* src = reinterpret_cast<uint8*>(memory_src_);
 622  E :    uint8* dst = reinterpret_cast<uint8*>(memory_dst_);
 623    :  
 624    :    // Validate memory accesses.
 625  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 626    :      check_access_fn =
 627  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 628  E :      ASSERT_TRUE(check_access_fn != NULL);
 629    :  
 630  E :      for (int32 i = 0; i < memory_length_; ++i)
 631    :        ExpectSpecialMemoryErrorIsDetected(false, &dst[i], &src[i], 0xDEADDEAD,
 632  E :                                           HeapProxy::UNKNOWN_BAD_ACCESS);
 633  E :    }
 634    :  
 635  E :    FreeMemoryBuffers();
 636  E :  }
 637    :  
 638  E :  TEST_F(AsanRtlTest, AsanSingleSpecial2byteInstructionCheckGoodAccess) {
 639    :    static const char* function_names[] = {
 640    :        "asan_check_2_byte_movs_access",
 641    :        "asan_check_2_byte_cmps_access",
 642    :        "asan_check_2_byte_stos_access"
 643    :    };
 644    :  
 645    :    // Setup the callback to detect invalid accesses.
 646  E :    SetCallBackFunction(&AsanErrorCallback);
 647    :  
 648    :    // Allocate memory space.
 649  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint16));
 650  E :    uint16* src = reinterpret_cast<uint16*>(memory_src_);
 651  E :    uint16* dst = reinterpret_cast<uint16*>(memory_dst_);
 652    :  
 653    :    // Validate memory accesses.
 654  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 655    :      check_access_fn =
 656  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 657  E :      ASSERT_TRUE(check_access_fn != NULL);
 658    :  
 659  E :      for (int32 i = 0; i < memory_length_; ++i)
 660    :        ExpectSpecialMemoryErrorIsDetected(false, &dst[i], &src[i], 0xDEADDEAD,
 661  E :                                           HeapProxy::UNKNOWN_BAD_ACCESS);
 662  E :    }
 663    :  
 664  E :    FreeMemoryBuffers();
 665  E :  }
 666    :  
 667  E :  TEST_F(AsanRtlTest, AsanSingleSpecial4byteInstructionCheckGoodAccess) {
 668    :    static const char* function_names[] = {
 669    :        "asan_check_4_byte_movs_access",
 670    :        "asan_check_4_byte_cmps_access",
 671    :        "asan_check_4_byte_stos_access"
 672    :    };
 673    :  
 674    :    // Setup the callback to detect invalid accesses.
 675  E :    SetCallBackFunction(&AsanErrorCallback);
 676    :  
 677    :    // Allocate memory space.
 678  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 679  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 680  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 681    :  
 682    :    // Validate memory accesses.
 683  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 684    :      check_access_fn =
 685  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 686  E :      ASSERT_TRUE(check_access_fn != NULL);
 687    :  
 688  E :      for (int32 i = 0; i < memory_length_; ++i)
 689    :        ExpectSpecialMemoryErrorIsDetected(false, &dst[i], &src[i], 0xDEADDEAD,
 690  E :                                           HeapProxy::UNKNOWN_BAD_ACCESS);
 691  E :    }
 692    :  
 693  E :    FreeMemoryBuffers();
 694  E :  }
 695    :  
 696  E :  TEST_F(AsanRtlTest, AsanSingleSpecialInstructionCheckBadAccess) {
 697    :    static const char* function_names[] = {
 698    :        "asan_check_1_byte_movs_access",
 699    :        "asan_check_1_byte_cmps_access",
 700    :        "asan_check_2_byte_movs_access",
 701    :        "asan_check_2_byte_cmps_access",
 702    :        "asan_check_4_byte_movs_access",
 703    :        "asan_check_4_byte_cmps_access"
 704    :    };
 705    :  
 706    :    // Setup the callback to detect invalid accesses.
 707  E :    SetCallBackFunction(&AsanErrorCallback);
 708    :  
 709    :    // Allocate memory space.
 710  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 711  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 712  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 713    :  
 714    :    // Validate memory accesses.
 715  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 716    :      check_access_fn =
 717  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 718  E :      ASSERT_TRUE(check_access_fn != NULL);
 719    :  
 720    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[0], &src[-1], 0xDEADDEAD,
 721  E :                                         HeapProxy::HEAP_BUFFER_UNDERFLOW);
 722    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[-1], &src[0], 0xDEADDEAD,
 723  E :                                         HeapProxy::HEAP_BUFFER_UNDERFLOW);
 724    :  
 725    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[0], &src[memory_length_],
 726  E :          0xDEADDEAD, HeapProxy::HEAP_BUFFER_OVERFLOW);
 727    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[memory_length_], &src[0],
 728  E :          0xDEADDEAD, HeapProxy::HEAP_BUFFER_OVERFLOW);
 729  E :    }
 730    :  
 731  E :    FreeMemoryBuffers();
 732  E :  }
 733    :  
 734  E :  TEST_F(AsanRtlTest, AsanSingleStoInstructionCheckBadAccess) {
 735    :    static const char* function_names[] = {
 736    :        "asan_check_1_byte_stos_access",
 737    :        "asan_check_2_byte_stos_access",
 738    :        "asan_check_4_byte_stos_access"
 739    :    };
 740    :  
 741    :    // Setup the callback to detect invalid accesses.
 742  E :    SetCallBackFunction(&AsanErrorCallback);
 743    :  
 744    :    // Allocate memory space.
 745  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 746  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 747  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 748    :  
 749    :    // Validate memory accesses.
 750  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 751    :      check_access_fn =
 752  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 753  E :      ASSERT_TRUE(check_access_fn != NULL);
 754    :  
 755    :      ExpectSpecialMemoryErrorIsDetected(false, &dst[0], &src[-1], 0xDEAD,
 756  E :          HeapProxy::HEAP_BUFFER_UNDERFLOW);
 757    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[-1], &src[0], 0xDEAD,
 758  E :          HeapProxy::HEAP_BUFFER_UNDERFLOW);
 759    :  
 760    :      ExpectSpecialMemoryErrorIsDetected(false, &dst[0], &src[memory_length_],
 761  E :          0xDEADDEAD, HeapProxy::HEAP_BUFFER_OVERFLOW);
 762    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[memory_length_], &src[0],
 763  E :          0xDEADDEAD, HeapProxy::HEAP_BUFFER_OVERFLOW);
 764  E :    }
 765    :  
 766  E :    FreeMemoryBuffers();
 767  E :  }
 768    :  
 769  E :  TEST_F(AsanRtlTest, AsanPrefixedSpecialInstructionCheckGoodAccess) {
 770    :    static const char* function_names[] = {
 771    :        "asan_check_repz_4_byte_movs_access",
 772    :        "asan_check_repz_4_byte_cmps_access",
 773    :        "asan_check_repz_4_byte_stos_access"
 774    :    };
 775    :  
 776    :    // Setup the callback to detect invalid accesses.
 777  E :    SetCallBackFunction(&AsanErrorCallback);
 778    :  
 779    :    // Allocate memory space.
 780  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 781  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 782  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 783    :  
 784    :    // Validate memory accesses.
 785  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 786    :      check_access_fn =
 787  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 788  E :      ASSERT_TRUE(check_access_fn != NULL);
 789    :  
 790    :      ExpectSpecialMemoryErrorIsDetected(false, &dst[0], &src[0], memory_length_,
 791  E :                                         HeapProxy::UNKNOWN_BAD_ACCESS);
 792  E :    }
 793    :  
 794  E :    FreeMemoryBuffers();
 795  E :  }
 796    :  
 797  E :  TEST_F(AsanRtlTest, AsanPrefixedSpecialInstructionCheckBadAccess) {
 798    :    static const char* function_names[] = {
 799    :        "asan_check_repz_4_byte_movs_access",
 800    :        "asan_check_repz_4_byte_cmps_access",
 801    :        "asan_check_repz_4_byte_stos_access"
 802    :    };
 803    :  
 804    :    // Setup the callback to detect invalid accesses.
 805  E :    SetCallBackFunction(&AsanErrorCallback);
 806    :  
 807    :    // Allocate memory space.
 808  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 809  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 810  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 811    :  
 812    :    // Validate memory accesses.
 813  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 814    :      check_access_fn =
 815  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 816  E :      ASSERT_TRUE(check_access_fn != NULL);
 817    :  
 818    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[0], &src[0],
 819  E :          memory_length_ + 1, HeapProxy::HEAP_BUFFER_OVERFLOW);
 820    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[-1], &src[-1],
 821  E :          memory_length_, HeapProxy::HEAP_BUFFER_UNDERFLOW);
 822    :      ExpectSpecialMemoryErrorIsDetected(true, &dst[-1], &src[0],
 823  E :          memory_length_, HeapProxy::HEAP_BUFFER_UNDERFLOW);
 824  E :    }
 825    :  
 826  E :    FreeMemoryBuffers();
 827  E :  }
 828    :  
 829  E :  TEST_F(AsanRtlTest, AsanDirectionSpecialInstructionCheckGoodAccess) {
 830    :    static const char* function_names[] = {
 831    :        "asan_check_repz_4_byte_movs_access",
 832    :        "asan_check_repz_4_byte_cmps_access",
 833    :        "asan_check_repz_4_byte_stos_access"
 834    :    };
 835    :  
 836    :    // Setup the callback to detect invalid accesses.
 837  E :    SetCallBackFunction(&AsanErrorCallback);
 838    :  
 839    :    // Force direction flag to backward.
 840  E :    direction_flag_forward = false;
 841    :  
 842    :    // Allocate memory space.
 843  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 844  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 845  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 846    :  
 847    :    // Validate memory accesses.
 848  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 849    :      check_access_fn =
 850  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 851  E :      ASSERT_TRUE(check_access_fn != NULL);
 852    :  
 853    :      ExpectSpecialMemoryErrorIsDetected(false, &dst[memory_length_ - 1],
 854    :          &src[memory_length_ - 1], memory_length_,
 855  E :          HeapProxy::UNKNOWN_BAD_ACCESS);
 856  E :    }
 857    :  
 858    :    // Reset direction flag to forward.
 859  E :    direction_flag_forward = true;
 860    :  
 861  E :    FreeMemoryBuffers();
 862  E :  }
 863    :  
 864  E :  TEST_F(AsanRtlTest, AsanSpecialInstructionCheckZeroAccess) {
 865    :    static const char* function_names[] = {
 866    :        "asan_check_repz_1_byte_movs_access",
 867    :        "asan_check_repz_1_byte_cmps_access",
 868    :        "asan_check_repz_1_byte_stos_access",
 869    :        "asan_check_repz_2_byte_movs_access",
 870    :        "asan_check_repz_2_byte_cmps_access",
 871    :        "asan_check_repz_2_byte_stos_access",
 872    :        "asan_check_repz_4_byte_movs_access",
 873    :        "asan_check_repz_4_byte_cmps_access",
 874    :        "asan_check_repz_4_byte_stos_access"
 875    :    };
 876    :  
 877    :    // Setup the callback to detect invalid accesses.
 878  E :    SetCallBackFunction(&AsanErrorCallback);
 879    :  
 880    :    // Allocate memory space.
 881  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 882  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 883  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 884    :  
 885    :    // Validate memory accesses.
 886  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 887    :      check_access_fn =
 888  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 889  E :      ASSERT_TRUE(check_access_fn != NULL);
 890    :  
 891    :      // A prefixed instruction with a count of zero do not have side effects.
 892    :      ExpectSpecialMemoryErrorIsDetected(false, &dst[-1], &src[-1], 0,
 893  E :                                         HeapProxy::UNKNOWN_BAD_ACCESS);
 894  E :    }
 895    :  
 896  E :    FreeMemoryBuffers();
 897  E :  }
 898    :  
 899  E :  TEST_F(AsanRtlTest, AsanSpecialInstructionCheckShortcutAccess) {
 900    :    static const char* function_names[] = {
 901    :        "asan_check_repz_1_byte_cmps_access",
 902    :        "asan_check_repz_2_byte_cmps_access",
 903    :        "asan_check_repz_4_byte_cmps_access",
 904    :    };
 905    :  
 906    :    // Setup the callback to detect invalid accesses.
 907  E :    SetCallBackFunction(&AsanErrorCallback);
 908    :  
 909    :    // Allocate memory space.
 910  E :    AllocMemoryBuffers(kAllocSize, sizeof(uint32));
 911  E :    uint32* src = reinterpret_cast<uint32*>(memory_src_);
 912  E :    uint32* dst = reinterpret_cast<uint32*>(memory_dst_);
 913    :  
 914  E :    src[1] = 0x12345667;
 915    :  
 916    :    // Validate memory accesses.
 917  E :    for (int32 function = 0; function < arraysize(function_names); ++function) {
 918    :      check_access_fn =
 919  E :          ::GetProcAddress(asan_rtl_, function_names[function]);
 920  E :      ASSERT_TRUE(check_access_fn != NULL);
 921    :  
 922    :      // Compare instruction stop their execution when values differ.
 923    :      ExpectSpecialMemoryErrorIsDetected(false, &dst[0], &src[0],
 924  E :          memory_length_ + 1, HeapProxy::UNKNOWN_BAD_ACCESS);
 925  E :    }
 926    :  
 927  E :    FreeMemoryBuffers();
 928  E :  }
 929    :  
 930  E :  TEST_F(AsanRtlTest, AsanCheckMemset) {
 931  E :    const size_t kAllocSize = 13;
 932  E :    ScopedASanAlloc<uint8> mem(this, kAllocSize);
 933  E :    ASSERT_TRUE(mem.get() != NULL);
 934  E :    memory_error_detected = false;
 935    :  
 936  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
 937  E :    EXPECT_EQ(mem.get(), memsetFunction(mem.GetAs<void*>(), 0xAA, kAllocSize));
 938  E :    EXPECT_FALSE(memory_error_detected);
 939  E :    for (size_t i = 0; i < kAllocSize; ++i)
 940  E :      EXPECT_EQ(0xAA, mem[i]);
 941    :  
 942    :    // mem[-1] points to the block header, we need to make sure that it doesn't
 943    :    // contain the value we're looking for.
 944  E :    uint8 last_block_header_byte = mem[-1];
 945  E :    mem[-1] = 0;
 946  E :    EXPECT_EQ(mem.get() - 1, memsetFunction(mem.get() - 1, 0xBB, kAllocSize));
 947  E :    EXPECT_TRUE(memory_error_detected);
 948  E :    for (size_t i = 0; i < kAllocSize; ++i)
 949  E :      EXPECT_EQ(0xBB, mem[i - 1]);
 950  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
 951  E :    mem[-1] = last_block_header_byte;
 952  E :    ResetLog();
 953    :  
 954  E :    memory_error_detected = false;
 955  E :    EXPECT_EQ(mem.get(), memsetFunction(mem.get(), 0xCC, kAllocSize + 1));
 956  E :    for (size_t i = 0; i < kAllocSize + 1; ++i)
 957  E :      EXPECT_EQ(0xCC, mem[i]);
 958  E :    EXPECT_TRUE(memory_error_detected);
 959  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
 960  E :    ResetLog();
 961    :  
 962  E :  }
 963    :  
 964  E :  TEST_F(AsanRtlTest, AsanCheckMemchr) {
 965  E :    const size_t kAllocSize = 13;
 966  E :    ScopedASanAlloc<uint8> mem(this, kAllocSize);
 967  E :    ASSERT_TRUE(mem.get() != NULL);
 968  E :    memset(mem.get(), 0, kAllocSize);
 969  E :    mem[4] = 0xAA;
 970  E :    memory_error_detected = false;
 971    :  
 972  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
 973  E :    EXPECT_EQ(mem.get() + 4, memchrFunction(mem.get(), mem[4], kAllocSize));
 974  E :    EXPECT_EQ(NULL, memchrFunction(mem.get(), mem[4] + 1, kAllocSize));
 975  E :    EXPECT_FALSE(memory_error_detected);
 976    :  
 977    :    // mem[-1] points to the block header, we need to make sure that it doesn't
 978    :    // contain the value we're looking for.
 979  E :    uint8 last_block_header_byte = mem[-1];
 980  E :    mem[-1] = 0;
 981  E :    EXPECT_EQ(mem.get() + 4, memchrFunction(mem.get() - 1, mem[4], kAllocSize));
 982  E :    EXPECT_TRUE(memory_error_detected);
 983  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
 984  E :    mem[-1] = last_block_header_byte;
 985  E :    ResetLog();
 986    :  
 987  E :    memory_error_detected = false;
 988  E :    EXPECT_EQ(mem.get() + 4, memchrFunction(mem.get() + 1, mem[4], kAllocSize));
 989  E :    EXPECT_TRUE(memory_error_detected);
 990  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
 991  E :    ResetLog();
 992    :  
 993  E :  }
 994    :  
 995  E :  TEST_F(AsanRtlTest, AsanCheckMemmove) {
 996  E :    const size_t kAllocSize = 13;
 997  E :    ScopedASanAlloc<uint8> mem_src(this, kAllocSize);
 998  E :    ASSERT_TRUE(mem_src.get() != NULL);
 999  E :    memory_error_detected = false;
1000    :    // Fill the array with value going from 0 to kAllocSize;
1001  E :    for (size_t i = 0; i < kAllocSize; ++i)
1002  E :      mem_src[i] = i;
1003    :  
1004  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1005    :    // Shift all the value from one index to the right.
1006    :    EXPECT_EQ(mem_src.get() + 1,
1007  E :              memmoveFunction(mem_src.get() + 1, mem_src.get(), kAllocSize - 1));
1008  E :    EXPECT_FALSE(memory_error_detected);
1009  E :    EXPECT_EQ(0, mem_src[0]);
1010  E :    for (size_t i = 1; i < kAllocSize; ++i)
1011  E :      EXPECT_EQ(i - 1, mem_src[i]);
1012    :  
1013    :    // Re-shift them to the left.
1014    :    EXPECT_EQ(mem_src.get(),
1015  E :              memmoveFunction(mem_src.get(), mem_src.get() + 1, kAllocSize));
1016  E :    EXPECT_TRUE(memory_error_detected);
1017  E :    for (size_t i = 0; i < kAllocSize - 1; ++i)
1018  E :      EXPECT_EQ(i, mem_src[i]);
1019  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1020  E :    ResetLog();
1021    :  
1022  E :    memory_error_detected = false;
1023    :    // Shift them to the left one more time.
1024    :  
1025    :    // mem_src[-1] points to the block header, we need to make sure that it
1026    :    // doesn't contain the value we're looking for.
1027  E :    uint8 last_block_header_byte = mem_src[-1];
1028  E :    mem_src[-1] = 0;
1029    :    EXPECT_EQ(mem_src.get() - 1,
1030  E :              memmoveFunction(mem_src.get() - 1, mem_src.get(), kAllocSize));
1031  E :    EXPECT_TRUE(memory_error_detected);
1032  E :    for (int i = -1; i < static_cast<int>(kAllocSize) - 2; ++i)
1033  E :      EXPECT_EQ(i + 1, mem_src[i]);
1034  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1035  E :    mem_src[-1] = last_block_header_byte;
1036  E :    ResetLog();
1037  E :  }
1038    :  
1039  E :  TEST_F(AsanRtlTest, AsanCheckMemcpy) {
1040  E :    const size_t kAllocSize = 13;
1041  E :    ScopedASanAlloc<uint8> mem_src(this, kAllocSize);
1042  E :    ASSERT_TRUE(mem_src.get() != NULL);
1043  E :    ScopedASanAlloc<uint8> mem_dst(this, kAllocSize);
1044  E :    ASSERT_TRUE(mem_dst.get() != NULL);
1045  E :    memory_error_detected = false;
1046    :    // Fill the array with value going from 0 to kAllocSize;
1047  E :    for (size_t i = 0; i < kAllocSize; ++i) {
1048  E :      mem_src[i] = i;
1049  E :      mem_dst[i] = ~i;
1050  E :    }
1051    :  
1052  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1053    :    EXPECT_EQ(mem_dst.get(),
1054  E :              memcpyFunction(mem_dst.get(), mem_src.get(), kAllocSize));
1055  E :    EXPECT_FALSE(memory_error_detected);
1056  E :    for (size_t i = 0; i < kAllocSize; ++i)
1057  E :      EXPECT_EQ(mem_dst[i], mem_src[i]);
1058    :  
1059    :    EXPECT_EQ(mem_dst.get(),
1060  E :              memcpyFunction(mem_dst.get(), mem_src.get(), kAllocSize + 1));
1061  E :    EXPECT_TRUE(memory_error_detected);
1062  E :    for (size_t i = 0; i < kAllocSize + 1; ++i)
1063  E :      EXPECT_EQ(mem_dst[i], mem_src[i]);
1064  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1065  E :    ResetLog();
1066    :  
1067  E :    memory_error_detected = false;
1068  E :    uint8 last_block_header_byte = mem_dst[-1];
1069  E :    mem_dst[-1] = 0;
1070    :    EXPECT_EQ(mem_dst.get(),
1071  E :              memcpyFunction(mem_dst.get(), mem_src.get() - 1, kAllocSize));
1072  E :    EXPECT_TRUE(memory_error_detected);
1073  E :    for (int i = -1; i < static_cast<int>(kAllocSize) - 1; ++i)
1074  E :      EXPECT_EQ(mem_dst[i + 1], mem_src[i]);
1075  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1076  E :    mem_dst[-1] = last_block_header_byte;
1077  E :    ResetLog();
1078  E :  }
1079    :  
1080  E :  TEST_F(AsanRtlTest, AsanCheckStrcspn) {
1081  E :    const char* str_value = "abc1";
1082  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1083  E :    ASSERT_TRUE(str.get() != NULL);
1084  E :    strcpy(str.get(), str_value);
1085    :  
1086  E :    const char* keys_value = "12";
1087  E :    ScopedASanAlloc<char> keys(this, strlen(keys_value) + 1);
1088  E :    ASSERT_TRUE(keys.get() != NULL);
1089  E :    strcpy(keys.get(), keys_value);
1090    :  
1091  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1092  E :    memory_error_detected = false;
1093    :  
1094    :    EXPECT_EQ(strcspn(str.get(), keys.get()),
1095  E :              strcspnFunction(str.get(), keys.get()));
1096  E :    EXPECT_FALSE(memory_error_detected);
1097    :  
1098    :    // str[-1] points to the block header, we need to make sure that it doesn't
1099    :    // contain the value \0.
1100  E :    uint8 last_block_header_byte = str[-1];
1101  E :    str[-1] = 'a';
1102    :    EXPECT_EQ(strcspn(str.get() - 1, keys.get()),
1103  E :              strcspnFunction(str.get() - 1, keys.get()));
1104  E :    EXPECT_TRUE(memory_error_detected);
1105  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1106  E :    str[-1] = last_block_header_byte;
1107  E :    ResetLog();
1108    :  
1109  E :    memory_error_detected = false;
1110  E :    size_t keys_len = strlen(keys.get());
1111  E :    keys[keys_len] = 'a';
1112  E :    keys[keys_len + 1] = 0;
1113    :    EXPECT_EQ(strcspn(str.get(), keys.get()),
1114  E :              strcspnFunction(str.get(), keys.get()));
1115  E :    EXPECT_TRUE(memory_error_detected);
1116  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1117  E :    ResetLog();
1118  E :  }
1119    :  
1120  E :  TEST_F(AsanRtlTest, AsanCheckStrlen) {
1121  E :    const char* str_value = "test_strlen";
1122  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1123  E :    ASSERT_TRUE(str != NULL);
1124  E :    strcpy(str.get(), str_value);
1125    :  
1126  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1127  E :    memory_error_detected = false;
1128    :  
1129  E :    EXPECT_EQ(strlen(str.get()), strlenFunction(str.get()));
1130  E :    EXPECT_FALSE(memory_error_detected);
1131    :  
1132    :    // str[-1] points to the block header, we need to make sure that it doesn't
1133    :    // contain the value \0.
1134  E :    uint8 last_block_header_byte = str[-1];
1135  E :    str[-1] = 'a';
1136  E :    EXPECT_EQ(strlen(str.get() - 1), strlenFunction(str.get() - 1));
1137  E :    EXPECT_TRUE(memory_error_detected);
1138  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1139  E :    str[-1] = last_block_header_byte;
1140  E :    ResetLog();
1141    :  
1142  E :    memory_error_detected = false;
1143  E :    size_t str_len = strlen(str.get());
1144  E :    str[str_len] = 'a';
1145  E :    str[str_len + 1] = 0;
1146  E :    EXPECT_EQ(strlen(str.get()), strlenFunction(str.get()));
1147  E :    EXPECT_TRUE(memory_error_detected);
1148  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1149  E :    ResetLog();
1150  E :  }
1151    :  
1152  E :  TEST_F(AsanRtlTest, AsanCheckStrrchr) {
1153  E :    const char* str_value = "test_strrchr";
1154  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1155  E :    ASSERT_TRUE(str != NULL);
1156  E :    strcpy(str.get(), str_value);
1157    :  
1158  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1159  E :    memory_error_detected = false;
1160    :  
1161  E :    EXPECT_EQ(strrchr(str.get(), 'c'), strrchrFunction(str.get(), 'c'));
1162  E :    EXPECT_FALSE(memory_error_detected);
1163  E :    EXPECT_EQ(strrchr(str.get(), 'z'), strrchrFunction(str.get(), 'z'));
1164  E :    EXPECT_FALSE(memory_error_detected);
1165    :  
1166    :    // str[-1] points to the block header, we need to make sure that it doesn't
1167    :    // contain the value \0.
1168  E :    uint8 last_block_header_byte = str[-1];
1169  E :    str[-1] = 'a';
1170  E :    EXPECT_EQ(strrchr(str.get() - 1, 'c'), strrchrFunction(str.get() - 1, 'c'));
1171  E :    EXPECT_TRUE(memory_error_detected);
1172  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1173  E :    str[-1] = last_block_header_byte;
1174  E :    ResetLog();
1175    :  
1176  E :    memory_error_detected = false;
1177  E :    size_t str_len = strlen(str.get());
1178  E :    str[str_len] = 'a';
1179  E :    str[str_len + 1] = 0;
1180  E :    EXPECT_EQ(strrchr(str.get(), 'c'), strrchrFunction(str.get(), 'c'));
1181  E :    EXPECT_TRUE(memory_error_detected);
1182  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1183  E :    ResetLog();
1184  E :  }
1185    :  
1186  E :  TEST_F(AsanRtlTest, AsanCheckStrcmp) {
1187  E :    const char* str_value = "test_strcmp";
1188  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1189  E :    ASSERT_TRUE(str.get() != NULL);
1190  E :    strcpy(str.get(), str_value);
1191    :  
1192  E :    const char* keys_value = "strcmp";
1193  E :    ScopedASanAlloc<char> keys(this, strlen(keys_value) + 1);
1194  E :    ASSERT_TRUE(keys != NULL);
1195  E :    strcpy(keys.get(), keys_value);
1196    :  
1197  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1198  E :    memory_error_detected = false;
1199    :  
1200    :    EXPECT_EQ(strcmp(str.get(), keys.get()),
1201  E :              strcmpFunction(str.get(), keys.get()));
1202  E :    EXPECT_FALSE(memory_error_detected);
1203    :  
1204    :    // str[-1] points to the block header, we need to make sure that it doesn't
1205    :    // contain the value \0.
1206  E :    uint8 last_block_header_byte = str[-1];
1207  E :    str[-1] = 'a';
1208    :    EXPECT_EQ(strcmp(str.get() - 1, keys.get()),
1209  E :              strcmpFunction(str.get() - 1, keys.get()));
1210  E :    EXPECT_TRUE(memory_error_detected);
1211  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1212  E :    str[-1] = last_block_header_byte;
1213  E :    ResetLog();
1214    :  
1215  E :    memory_error_detected = false;
1216  E :    size_t keys_len = strlen(keys.get());
1217  E :    keys[keys_len] = 'a';
1218  E :    keys[keys_len + 1] = 0;
1219    :    EXPECT_EQ(strcmp(str.get(), keys.get()),
1220  E :              strcmpFunction(str.get(), keys.get()));
1221  E :    EXPECT_TRUE(memory_error_detected);
1222  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1223  E :    ResetLog();
1224  E :  }
1225    :  
1226  E :  TEST_F(AsanRtlTest, AsanCheckStrpbrk) {
1227  E :    const char* str_value = "test_strpbrk";
1228  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1229  E :    ASSERT_TRUE(str != NULL);
1230  E :    strcpy(str.get(), str_value);
1231    :  
1232  E :    const char* keys_value = "strpbrk";
1233  E :    ScopedASanAlloc<char> keys(this, strlen(keys_value) + 1);
1234  E :    ASSERT_TRUE(keys != NULL);
1235  E :    strcpy(keys.get(), keys_value);
1236    :  
1237  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1238  E :    memory_error_detected = false;
1239    :  
1240    :    EXPECT_EQ(strpbrk(str.get(), keys.get()),
1241  E :              strpbrkFunction(str.get(), keys.get()));
1242  E :    EXPECT_FALSE(memory_error_detected);
1243    :  
1244    :    // str[-1] points to the block header, we need to make sure that it doesn't
1245    :    // contain the value \0.
1246  E :    uint8 last_block_header_byte = str[-1];
1247  E :    str[-1] = 'a';
1248    :    EXPECT_EQ(strpbrk(str.get() - 1, keys.get()),
1249  E :              strpbrkFunction(str.get() - 1, keys.get()));
1250  E :    EXPECT_TRUE(memory_error_detected);
1251  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1252  E :    str[-1] = last_block_header_byte;
1253  E :    ResetLog();
1254    :  
1255  E :    memory_error_detected = false;
1256  E :    size_t keys_len = strlen(keys.get());
1257  E :    keys[keys_len] = 'a';
1258  E :    keys[keys_len + 1] = 0;
1259    :    EXPECT_EQ(strpbrk(str.get(), keys.get()),
1260  E :              strpbrkFunction(str.get(), keys.get()));
1261  E :    EXPECT_TRUE(memory_error_detected);
1262  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1263  E :    ResetLog();
1264  E :  }
1265    :  
1266  E :  TEST_F(AsanRtlTest, AsanCheckStrstr) {
1267  E :    const char* str_value = "test_strstr";
1268  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1269  E :    ASSERT_TRUE(str != NULL);
1270  E :    strcpy(str.get(), str_value);
1271    :  
1272  E :    const char* keys_value = "strstr";
1273  E :    ScopedASanAlloc<char> keys(this, strlen(keys_value) + 1);
1274  E :    ASSERT_TRUE(keys != NULL);
1275  E :    strcpy(keys.get(), keys_value);
1276    :  
1277  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1278  E :    memory_error_detected = false;
1279    :  
1280    :    EXPECT_EQ(strstr(str.get(), keys.get()),
1281  E :              strstrFunction(str.get(), keys.get()));
1282  E :    EXPECT_FALSE(memory_error_detected);
1283    :  
1284    :    // str[-1] points to the block header, we need to make sure that it doesn't
1285    :    // contain the value \0.
1286  E :    uint8 last_block_header_byte = str[-1];
1287  E :    str[-1] = 'a';
1288    :    EXPECT_EQ(strstr(str.get() - 1, keys.get()),
1289  E :              strstrFunction(str.get() - 1, keys.get()));
1290  E :    EXPECT_TRUE(memory_error_detected);
1291  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1292  E :    str[-1] = last_block_header_byte;
1293  E :    ResetLog();
1294    :  
1295  E :    memory_error_detected = false;
1296  E :    size_t keys_len = strlen(keys.get());
1297  E :    keys[keys_len] = 'a';
1298  E :    keys[keys_len + 1] = 0;
1299    :    EXPECT_EQ(strstr(str.get(), keys.get()),
1300  E :              strstrFunction(str.get(), keys.get()));
1301  E :    EXPECT_TRUE(memory_error_detected);
1302  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1303  E :    ResetLog();
1304  E :  }
1305    :  
1306  E :  TEST_F(AsanRtlTest, AsanCheckStrspn) {
1307  E :    const char* str_value = "test_strspn";
1308  E :    ScopedASanAlloc<char> str(this, strlen(str_value) + 1);
1309  E :    ASSERT_TRUE(str != NULL);
1310  E :    strcpy(str.get(), str_value);
1311    :  
1312  E :    const char* keys_value = "strspn";
1313  E :    ScopedASanAlloc<char> keys(this, strlen(keys_value) + 1);
1314  E :    ASSERT_TRUE(keys != NULL);
1315  E :    strcpy(keys.get(), keys_value);
1316    :  
1317  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1318  E :    memory_error_detected = false;
1319    :  
1320    :    EXPECT_EQ(strspn(str.get(), keys.get()),
1321  E :              strspnFunction(str.get(), keys.get()));
1322  E :    EXPECT_FALSE(memory_error_detected);
1323    :  
1324    :    // str[-1] points to the block header, we need to make sure that it doesn't
1325    :    // contain the value \0.
1326  E :    uint8 last_block_header_byte = str[-1];
1327  E :    str[-1] = 'a';
1328    :    EXPECT_EQ(strspn(str.get() - 1, keys.get()),
1329  E :              strspnFunction(str.get() - 1, keys.get()));
1330  E :    EXPECT_TRUE(memory_error_detected);
1331  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1332  E :    str[-1] = last_block_header_byte;
1333  E :    ResetLog();
1334    :  
1335  E :    memory_error_detected = false;
1336  E :    size_t keys_len = strlen(keys.get());
1337  E :    keys[keys_len] = 'a';
1338  E :    keys[keys_len + 1] = 0;
1339    :    EXPECT_EQ(strspn(str.get(), keys.get()),
1340  E :              strspnFunction(str.get(), keys.get()));
1341  E :    EXPECT_TRUE(memory_error_detected);
1342  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1343  E :    ResetLog();
1344  E :  }
1345    :  
1346  E :  TEST_F(AsanRtlTest, AsanCheckStrncpy) {
1347  E :    const char* str_value = "test_strncpy";
1348  E :    ScopedASanAlloc<char> source(this, strlen(str_value) + 1);
1349  E :    ASSERT_TRUE(source != NULL);
1350  E :    strcpy(source.get(), str_value);
1351    :  
1352  E :    const char* long_str_value = "test_strncpy_long_source";
1353  E :    ScopedASanAlloc<char> long_source(this, strlen(long_str_value) + 1);
1354  E :    ASSERT_TRUE(long_source.get() != NULL);
1355  E :    strcpy(long_source.get(), long_str_value);
1356    :  
1357  E :    ScopedASanAlloc<char> destination(this, strlen(str_value) + 1);
1358  E :    ASSERT_TRUE(destination != NULL);
1359    :  
1360  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1361  E :    memory_error_detected = false;
1362    :  
1363    :    EXPECT_EQ(destination.get(),
1364    :              strncpyFunction(destination.get(),
1365    :                              source.get(),
1366  E :                              strlen(str_value)));
1367  E :    EXPECT_FALSE(memory_error_detected);
1368    :  
1369    :    // Test an underflow on the source.
1370  E :    uint8 last_block_header_byte = source[-1];
1371  E :    source[-1] = 'a';
1372    :    EXPECT_EQ(destination.get(),
1373    :              strncpyFunction(destination.get(),
1374    :                              source.get() - 1,
1375  E :                              strlen(str_value)));
1376  E :    EXPECT_TRUE(memory_error_detected);
1377  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1378  E :    source[-1] = last_block_header_byte;
1379  E :    ResetLog();
1380    :  
1381    :    // Test an underflow on the destination.
1382  E :    memory_error_detected = false;
1383  E :    last_block_header_byte = destination[-1];
1384  E :    destination[-1] = 'a';
1385    :    EXPECT_EQ(destination.get() - 1,
1386    :              strncpyFunction(destination.get() - 1,
1387    :                              source.get(),
1388  E :                              strlen(str_value)));
1389  E :    EXPECT_TRUE(memory_error_detected);
1390  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1391  E :    destination[-1] = last_block_header_byte;
1392  E :    ResetLog();
1393    :  
1394    :    // Test an overflow on the destination.
1395  E :    memory_error_detected = false;
1396    :    EXPECT_EQ(destination.get(),
1397    :              strncpyFunction(destination.get(),
1398    :                              long_source.get(),
1399  E :                              strlen(long_str_value)));
1400  E :    EXPECT_TRUE(memory_error_detected);
1401  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1402  E :    ResetLog();
1403    :  
1404    :    // Another overflow on the destination.
1405  E :    memory_error_detected = false;
1406    :    EXPECT_EQ(destination,
1407    :              strncpyFunction(destination.get(),
1408    :                              source.get(),
1409  E :                              strlen(str_value) + 2));
1410  E :    EXPECT_TRUE(memory_error_detected);
1411  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1412  E :    ResetLog();
1413    :  
1414    :    // Test an overflow on the source.
1415  E :    size_t source_len = strlen(source.get());
1416  E :    source[source_len] = 'a';
1417  E :    source[source_len + 1] = 0;
1418  E :    memory_error_detected = false;
1419    :    EXPECT_EQ(destination.get(), strncpyFunction(destination.get(),
1420    :                                                 source.get(),
1421  E :                                                 strlen(source.get()) + 1));
1422  E :    EXPECT_TRUE(memory_error_detected);
1423  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1424  E :    ResetLog();
1425    :  
1426  E :    memory_error_detected = false;
1427    :    EXPECT_EQ(destination.get(), strncpyFunction(destination.get(),
1428    :                                                 source.get(),
1429  E :                                                 strlen(source.get())));
1430  E :    EXPECT_FALSE(memory_error_detected);
1431  E :    ResetLog();
1432  E :  }
1433    :  
1434  E :  TEST_F(AsanRtlTest, AsanCheckStrncat) {
1435  E :    const char* prefix_value = "test_";
1436  E :    const char* suffix_value = "strncat";
1437    :    char buffer[64];
1438    :  
1439    :    ScopedASanAlloc<char> mem(this,
1440  E :                              strlen(prefix_value) + strlen(suffix_value) + 1);
1441  E :    ASSERT_TRUE(mem != NULL);
1442  E :    strcpy(mem.get(), prefix_value);
1443  E :    strcpy(buffer, prefix_value);
1444    :  
1445  E :    ScopedASanAlloc<char> suffix(this, strlen(suffix_value) + 1);
1446  E :    ASSERT_TRUE(mem.get() != NULL);
1447  E :    strcpy(suffix.get(), suffix_value);
1448    :  
1449  E :    SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1450  E :    memory_error_detected = false;
1451    :  
1452    :    EXPECT_EQ(mem.get(),
1453  E :        strncatFunction(mem.get(), suffix.get(), strlen(suffix_value)));
1454  E :    EXPECT_FALSE(memory_error_detected);
1455    :    EXPECT_STRCASEEQ(
1456  E :        strncat(buffer, suffix.get(), strlen(suffix_value)), mem.get());
1457    :  
1458    :    // Test an underflow on the suffix.
1459  E :    uint8 last_block_header_byte = suffix[-1];
1460  E :    suffix[-1] = 'a';
1461  E :    strcpy(mem.get(), prefix_value);
1462  E :    strcpy(buffer, prefix_value);
1463    :    EXPECT_EQ(mem.get(),
1464  E :        strncatFunction(mem.get(), suffix.get() - 1, strlen(suffix_value)));
1465  E :    EXPECT_TRUE(memory_error_detected);
1466  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1467    :    EXPECT_STRCASEEQ(
1468  E :        strncat(buffer, suffix.get() - 1, strlen(suffix_value)), mem.get());
1469  E :    suffix[-1] = last_block_header_byte;
1470  E :    ResetLog();
1471    :  
1472    :    // Test an underflow on the destination.
1473  E :    memory_error_detected = false;
1474  E :    last_block_header_byte = mem[-1];
1475  E :    mem[-1] = 'a';
1476  E :    strcpy(mem.get(), prefix_value);
1477  E :    strcpy(buffer, prefix_value);
1478    :    EXPECT_EQ(mem.get() - 1,
1479  E :              strncatFunction(mem.get() - 1, suffix.get(), strlen(suffix_value)));
1480  E :    EXPECT_TRUE(memory_error_detected);
1481  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferUnderFlow));
1482    :    EXPECT_STRCASEEQ(
1483  E :        strncat(buffer, suffix.get(), strlen(suffix_value)), mem.get());
1484  E :    mem[-1] = last_block_header_byte;
1485  E :    ResetLog();
1486    :  
1487    :    // Test an overflow on the suffix.
1488  E :    size_t suffix_len = strlen(suffix.get());
1489  E :    suffix[suffix_len] = 'a';
1490  E :    suffix[suffix_len + 1] = 0;
1491  E :    memory_error_detected = false;
1492  E :    strcpy(mem.get(), prefix_value);
1493  E :    strcpy(buffer, prefix_value);
1494    :    EXPECT_EQ(mem.get(),
1495  E :        strncatFunction(mem.get(), suffix.get(), strlen(suffix.get()) + 1));
1496  E :    EXPECT_TRUE(memory_error_detected);
1497  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1498    :    EXPECT_STRCASEEQ(
1499  E :        strncat(buffer, suffix.get(), strlen(suffix.get())), mem.get());
1500  E :    ResetLog();
1501  E :    suffix[suffix_len] = 0;
1502    :  
1503    :    // Test an overflow on the destination.
1504  E :    memory_error_detected = false;
1505  E :    strcpy(mem.get(), prefix_value);
1506  E :    strcpy(buffer, prefix_value);
1507  E :    size_t prefix_len = strlen(prefix_value);
1508  E :    mem[prefix_len] = 'a';
1509  E :    mem[prefix_len + 1] = 0;
1510  E :    buffer[prefix_len] = 'a';
1511  E :    buffer[prefix_len + 1] = 0;
1512    :    EXPECT_EQ(mem.get(),
1513  E :        strncatFunction(mem.get(), suffix.get(), strlen(suffix.get())));
1514  E :    EXPECT_TRUE(memory_error_detected);
1515  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1516    :    EXPECT_STRCASEEQ(
1517  E :        strncat(buffer, suffix.get(), strlen(suffix.get())), mem.get());
1518  E :    ResetLog();
1519  E :  }
1520    :  
1521    :  namespace {
1522    :  
1523    :  // Helps to test the asan_ReadFile function.
1524    :  class AsanRtlReadFileTest : public AsanRtlTest {
1525    :   public:
1526    :    typedef AsanRtlTest Super;
1527    :  
1528  E :    AsanRtlReadFileTest() : temp_file_handle_(INVALID_HANDLE_VALUE) {
1529  E :    }
1530    :  
1531  E :    void SetUp() OVERRIDE {
1532  E :      Super::SetUp();
1533  E :      SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1534  E :      ASSERT_NO_FATAL_FAILURE(CreateTempFile());
1535  E :    }
1536    :  
1537  E :    void CreateTempFile() {
1538  E :      ASSERT_EQ(kTestStringLength,
1539    :                file_util::WriteFile(temp_file_.path(),
1540    :                                     kTestString,
1541    :                                     kTestStringLength));
1542    :  
1543    :      temp_file_handle_.Set(::CreateFile(temp_file_.path().value().c_str(),
1544  E :          GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
1545    :  
1546  E :      ASSERT_NE(INVALID_HANDLE_VALUE, temp_file_handle_.Get());
1547  E :    }
1548    :  
1549    :    static const char kTestString[];
1550    :    static const size_t kTestStringLength;
1551    :  
1552    :   protected:
1553    :    testing::ScopedTempFile temp_file_;
1554    :  
1555    :    base::win::ScopedHandle temp_file_handle_;
1556    :  };
1557    :  
1558    :  const char AsanRtlReadFileTest::kTestString[] = "Test of asan_ReadFile";
1559    :  const size_t AsanRtlReadFileTest::kTestStringLength =
1560    :      sizeof(AsanRtlReadFileTest::kTestString);
1561    :  
1562    :  }  // namespace
1563    :  
1564  E :  TEST_F(AsanRtlReadFileTest, AsanReadFile) {
1565    :    // Test that the function works correctly with valid parameters. In this case
1566    :    // we don't pass an OVERLAPPED structure to the function.
1567  E :    DWORD bytes_read = 0;
1568  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1569    :    EXPECT_TRUE(ReadFileFunction(temp_file_handle_.Get(),
1570    :                                 alloc.get(),
1571    :                                 kTestStringLength,
1572    :                                 &bytes_read,
1573  E :                                 NULL));
1574  E :    EXPECT_EQ(kTestStringLength, bytes_read);
1575  E :    EXPECT_STREQ(kTestString, alloc.get());
1576  E :    EXPECT_FALSE(memory_error_detected);
1577  E :  }
1578    :  
1579  E :  TEST_F(AsanRtlReadFileTest, AsanReadFileWithOverlapped) {
1580  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1581    :    // Test that the function works correctly with valid parameters. Here we pass
1582    :    // an OVERLAPPED structure to the function, which indicates that we want to do
1583    :    // the read from a given offset.
1584  E :    OVERLAPPED overlapped = {};
1585    :    // Start the read from the middle of the test string.
1586  E :    const size_t kOffset = kTestStringLength / 2;
1587  E :    overlapped.Offset = kOffset;
1588  E :    DWORD bytes_read = 0;
1589    :    EXPECT_TRUE(ReadFileFunction(temp_file_handle_.Get(),
1590    :                                 alloc.get(),
1591    :                                 kTestStringLength,
1592    :                                 &bytes_read,
1593  E :                                 &overlapped));
1594  E :    EXPECT_EQ(kTestStringLength - kOffset, bytes_read);
1595  E :    EXPECT_STREQ(kTestString + kOffset, alloc.get());
1596  E :    EXPECT_FALSE(memory_error_detected);
1597  E :  }
1598    :  
1599  E :  TEST_F(AsanRtlReadFileTest, AsanReadFileOverflow) {
1600    :    // Test that the function works correctly with valid parameters. In this case
1601    :    // we don't pass an OVERLAPPED structure to the function.
1602  E :    DWORD bytes_read = 0;
1603  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1604    :    EXPECT_TRUE(ReadFileFunction(temp_file_handle_.Get(),
1605    :                                 alloc.get(),
1606    :                                 kTestStringLength + 1,
1607    :                                 &bytes_read,
1608  E :                                 NULL));
1609  E :    EXPECT_EQ(kTestStringLength, bytes_read);
1610  E :    EXPECT_EQ(0U, ::strncmp(kTestString, alloc.get(), bytes_read));
1611  E :    EXPECT_TRUE(memory_error_detected);
1612  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1613  E :  }
1614    :  
1615  E :  TEST_F(AsanRtlReadFileTest, AsanReadFileUAFOnOverlapped) {
1616  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1617    :    // Test an use-after-free on the overlapped structure.
1618  E :    ScopedASanAlloc<OVERLAPPED> overlapped(this, sizeof(OVERLAPPED));
1619    :    // Start the read from the middle of the test string.
1620  E :    const size_t kOffset = kTestStringLength / 2;
1621  E :    overlapped->Offset = kOffset;
1622  E :    DWORD bytes_read = 0;
1623  E :    OVERLAPPED* overlapped_ptr = overlapped.get();
1624  E :    overlapped.reset(NULL);
1625    :    EXPECT_TRUE(ReadFileFunction(temp_file_handle_.Get(),
1626    :                                 alloc.get(),
1627    :                                 kTestStringLength,
1628    :                                 &bytes_read,
1629  E :                                 overlapped_ptr));
1630  E :    EXPECT_EQ(kTestStringLength - kOffset, bytes_read);
1631  E :    EXPECT_STREQ(kTestString + kOffset, alloc.get());
1632  E :    EXPECT_TRUE(memory_error_detected);
1633  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
1634  E :  }
1635    :  
1636  E :  TEST_F(AsanRtlReadFileTest, AsanReadFileUseAfterFree) {
1637    :    // Test if an use-after-free on the destination buffer is correctly detected.
1638  E :    DWORD bytes_read = 0;
1639  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1640  E :    char* alloc_ptr = alloc.get();
1641  E :    alloc.reset(NULL);
1642    :    EXPECT_TRUE(ReadFileFunction(temp_file_handle_.Get(),
1643    :                                 alloc_ptr,
1644    :                                 kTestStringLength + 1,
1645    :                                 &bytes_read,
1646  E :                                 NULL));
1647  E :    EXPECT_EQ(kTestStringLength, bytes_read);
1648  E :    EXPECT_STREQ(kTestString, alloc_ptr);
1649  E :    EXPECT_TRUE(memory_error_detected);
1650  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
1651  E :  }
1652    :  
1653    :  namespace {
1654    :  
1655    :  typedef ScopedASanAlloc<char>* AsanReadFileCallbackData;
1656    :  AsanReadFileCallbackData readfile_callback_data = NULL;
1657    :  
1658  E :  void AsanReadFileCallback() {
1659  E :    ASSERT_TRUE(readfile_callback_data != NULL);
1660  E :    readfile_callback_data->reset(NULL);
1661  E :  }
1662    :  
1663    :  }  // namespace
1664    :  
1665  E :  TEST_F(AsanRtlReadFileTest, AsanReadFileUAFAfterInternalCall) {
1666    :    // This test makes sure that use-after-free errors on the input buffer given
1667    :    // to the ReadFile function are correctly detected.
1668  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1669  E :    memset(alloc.get(), 0, kTestStringLength);
1670  E :    char* alloc_ptr = alloc.get();
1671  E :    readfile_callback_data = &alloc;
1672    :  
1673    :    // Set the callback that we want to use once the internal call to ReadFile
1674    :    // returns.
1675  E :    SetInterceptorCallbackFunction(&AsanReadFileCallback);
1676    :  
1677    :    // Read from the file using the interceptor, this will call the ReadFile
1678    :    // callback once the internal call to ReadFile returns, and result in freeing
1679    :    // the buffer.
1680  E :    DWORD bytes_read = 0;
1681    :    EXPECT_TRUE(ReadFileFunction(temp_file_handle_.Get(),
1682    :                                 alloc.get(),
1683    :                                 kTestStringLength,
1684    :                                 &bytes_read,
1685  E :                                 NULL));
1686    :  
1687  E :    EXPECT_EQ(kTestStringLength, bytes_read);
1688  E :    EXPECT_STREQ(kTestString, alloc_ptr);
1689  E :    EXPECT_TRUE(memory_error_detected);
1690  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
1691    :  
1692  E :    SetInterceptorCallbackFunction(NULL);
1693  E :  }
1694    :  
1695    :  namespace {
1696    :  
1697    :  // Helps to test the asan_WriteFile function.
1698    :  class AsanRtlWriteFileTest : public AsanRtlTest {
1699    :   public:
1700    :    typedef AsanRtlTest Super;
1701    :  
1702  E :    AsanRtlWriteFileTest()
1703    :        : temp_file_handle_(INVALID_HANDLE_VALUE) {
1704  E :    }
1705    :  
1706  E :    void SetUp() OVERRIDE {
1707  E :      Super::SetUp();
1708    :  
1709    :      temp_file_handle_.Set(::CreateFile(temp_file_.path().value().c_str(),
1710    :                                         GENERIC_READ | GENERIC_WRITE,
1711    :                                         0,
1712    :                                         NULL,
1713    :                                         OPEN_EXISTING,
1714    :                                         FILE_ATTRIBUTE_NORMAL,
1715  E :                                         NULL));
1716  E :      ASSERT_NE(INVALID_HANDLE_VALUE, temp_file_handle_.Get());
1717  E :      SetCallBackFunction(&AsanErrorCallbackWithoutComparingContext);
1718  E :    }
1719    :  
1720  E :    bool ReadFileContent(std::string* pipe_content, size_t kOffset) {
1721  E :      EXPECT_TRUE(pipe_content != NULL);
1722  E :      const size_t kMaxContentLength = 64;
1723  E :      pipe_content->clear();
1724  E :      pipe_content->resize(kMaxContentLength);
1725  E :      DWORD bytes_read = 0;
1726  E :      ::SetFilePointer(temp_file_handle_.Get(), kOffset, 0, FILE_BEGIN);
1727    :      if (::ReadFile(temp_file_handle_.Get(),
1728    :                     &(*pipe_content)[0],
1729    :                     kMaxContentLength,
1730    :                     &bytes_read,
1731  E :                     NULL) == FALSE) {
1732  i :        return false;
1733    :      }
1734    :      // Ensures that the buffer is big enough to store the pipe content.
1735  E :      EXPECT_TRUE(bytes_read < kMaxContentLength);
1736    :  
1737  E :      return true;
1738  E :    }
1739    :  
1740    :    static const char kTestString[];
1741    :    static const size_t kTestStringLength;
1742    :  
1743    :   protected:
1744    :    testing::ScopedTempFile temp_file_;
1745    :  
1746    :    base::win::ScopedHandle temp_file_handle_;
1747    :  };
1748    :  
1749    :  const char AsanRtlWriteFileTest::kTestString[] = "Test of asan_WriteFile";
1750    :  const size_t AsanRtlWriteFileTest::kTestStringLength =
1751    :      sizeof(AsanRtlWriteFileTest::kTestString);
1752    :  
1753    :  }  // namespace
1754    :  
1755  E :  TEST_F(AsanRtlWriteFileTest, AsanWriteFile) {
1756    :    // Test that the function works correctly with valid parameters. In this case
1757    :    // we don't pass an OVERLAPPED structure to the function.
1758  E :    DWORD bytes_written = 0;
1759  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1760    :    EXPECT_TRUE(WriteFileFunction(temp_file_handle_.Get(),
1761    :                                  kTestString,
1762    :                                  kTestStringLength,
1763    :                                  &bytes_written,
1764  E :                                  NULL));
1765  E :    EXPECT_EQ(kTestStringLength, bytes_written);
1766  E :    EXPECT_FALSE(memory_error_detected);
1767  E :    std::string file_content;
1768  E :    EXPECT_TRUE(ReadFileContent(&file_content, 0));
1769  E :    EXPECT_STREQ(kTestString, file_content.c_str());
1770  E :  }
1771    :  
1772  E :  TEST_F(AsanRtlWriteFileTest, AsanWriteFileWithOverlapped) {
1773  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1774    :    // Test that the function works correctly with valid parameters. Here we pass
1775    :    // an OVERLAPPED structure to the function, which indicates that we want to do
1776    :    // the write after a given offset.
1777  E :    OVERLAPPED overlapped = {};
1778    :    // Start the write from the middle of the test string.
1779  E :    const size_t kOffset = kTestStringLength / 2;
1780  E :    overlapped.Offset = kOffset;
1781  E :    DWORD bytes_written = 0;
1782    :    EXPECT_TRUE(WriteFileFunction(temp_file_handle_.Get(),
1783    :                                  kTestString + kOffset,
1784    :                                  kTestStringLength - kOffset,
1785    :                                  &bytes_written,
1786  E :                                  &overlapped));
1787  E :    EXPECT_EQ(kTestStringLength - kOffset, bytes_written);
1788  E :    EXPECT_FALSE(memory_error_detected);
1789  E :    std::string file_content;
1790  E :    EXPECT_TRUE(ReadFileContent(&file_content, kOffset));
1791  E :    EXPECT_STREQ(kTestString + kOffset, file_content.c_str());
1792  E :  }
1793    :  
1794  E :  TEST_F(AsanRtlWriteFileTest, AsanWriteFileOverflow) {
1795    :    // Test that the function works correctly with valid parameters. In this case
1796    :    // we don't pass an OVERLAPPED structure to the function.
1797  E :    DWORD bytes_written = 0;
1798  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1799  E :    strcpy(alloc.get(), kTestString);
1800    :    EXPECT_TRUE(WriteFileFunction(temp_file_handle_.Get(),
1801    :                                  alloc.get(),
1802    :                                  kTestStringLength + 1,
1803    :                                  &bytes_written,
1804  E :                                  NULL));
1805  E :    EXPECT_EQ(kTestStringLength + 1, bytes_written);
1806  E :    EXPECT_TRUE(memory_error_detected);
1807  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapBufferOverFlow));
1808  E :    std::string file_content;
1809  E :    EXPECT_TRUE(ReadFileContent(&file_content, 0));
1810  E :    EXPECT_STREQ(kTestString, file_content.c_str());
1811  E :  }
1812    :  
1813  E :  TEST_F(AsanRtlWriteFileTest, AsanWriteFileUAFOnOverlapped) {
1814    :    // Test an use-after-free on the overlapped structure.
1815  E :    ScopedASanAlloc<OVERLAPPED> overlapped(this, sizeof(OVERLAPPED));
1816    :    // Start the write from the middle of the test string.
1817  E :    const size_t kOffset = kTestStringLength / 2;
1818  E :    overlapped->Offset = kOffset;
1819  E :    DWORD bytes_written = 0;
1820  E :    OVERLAPPED* overlapped_ptr = overlapped.get();
1821  E :    overlapped.reset(NULL);
1822    :    EXPECT_TRUE(WriteFileFunction(temp_file_handle_.Get(),
1823    :                                  kTestString + kOffset,
1824    :                                  kTestStringLength - kOffset,
1825    :                                  &bytes_written,
1826  E :                                  overlapped_ptr));
1827  E :    EXPECT_EQ(kTestStringLength - kOffset, bytes_written);
1828  E :    EXPECT_TRUE(memory_error_detected);
1829  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
1830  E :    std::string file_content;
1831  E :    EXPECT_TRUE(ReadFileContent(&file_content, kOffset));
1832  E :    EXPECT_STREQ(kTestString + kOffset, file_content.c_str());
1833  E :  }
1834    :  
1835  E :  TEST_F(AsanRtlWriteFileTest, AsanWriteFileUseAfterFree) {
1836    :    // Test if an use-after-free on the destination buffer is correctly detected.
1837  E :    DWORD bytes_written = 0;
1838  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1839  E :    strcpy(alloc.get(), kTestString);
1840  E :    char* alloc_ptr = alloc.get();
1841  E :    alloc.reset(NULL);
1842    :    EXPECT_TRUE(WriteFileFunction(temp_file_handle_.Get(),
1843    :                                  alloc_ptr,
1844    :                                  kTestStringLength,
1845    :                                  &bytes_written,
1846  E :                                  NULL));
1847  E :    EXPECT_EQ(kTestStringLength, bytes_written);
1848  E :    EXPECT_TRUE(memory_error_detected);
1849  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
1850  E :    std::string file_content;
1851  E :    EXPECT_TRUE(ReadFileContent(&file_content, 0));
1852  E :    EXPECT_STREQ(kTestString, file_content.c_str());
1853  E :  }
1854    :  
1855    :  namespace {
1856    :  
1857    :  typedef ScopedASanAlloc<char>* AsanWriteFileCallbackData;
1858    :  AsanWriteFileCallbackData writefile_callback_data = NULL;
1859    :  
1860  E :  void AsanWriteFileCallback() {
1861  E :    ASSERT_TRUE(writefile_callback_data != NULL);
1862  E :    writefile_callback_data->reset(NULL);
1863  E :  }
1864    :  
1865    :  }  // namespace
1866    :  
1867  E :  TEST_F(AsanRtlWriteFileTest, AsanWriteFileUAFAfterInternalCall) {
1868    :    // This test makes sure that use-after-free errors on the input buffer given
1869    :    // to the WriteFile function are correctly detected.
1870  E :    ScopedASanAlloc<char> alloc(this, kTestStringLength);
1871  E :    strcpy(alloc.get(), kTestString);
1872    :  
1873  E :    writefile_callback_data = &alloc;
1874    :  
1875    :    // Set the callback that we want to use once the internal call to WriteFile
1876    :    // returns.
1877  E :    SetInterceptorCallbackFunction(&AsanWriteFileCallback);
1878    :  
1879    :    // Write to the file using the interceptor, this will call the WriteFile
1880    :    // callback once the internal call to WriteFile returns, and result in freeing
1881    :    // the buffer.
1882  E :    DWORD bytes_written = 0;
1883    :    EXPECT_TRUE(WriteFileFunction(temp_file_handle_.Get(),
1884    :                                  alloc.get(),
1885    :                                  kTestStringLength,
1886    :                                  &bytes_written,
1887  E :                                  NULL));
1888    :  
1889  E :    EXPECT_EQ(kTestStringLength, bytes_written);
1890    :  
1891  E :    EXPECT_TRUE(memory_error_detected);
1892  E :    EXPECT_TRUE(LogContains(HeapProxy::kHeapUseAfterFree));
1893    :  
1894  E :    std::string file_content;
1895  E :    EXPECT_TRUE(ReadFileContent(&file_content, 0));
1896  E :    EXPECT_STREQ(kTestString, file_content.c_str());
1897    :  
1898  E :    SetInterceptorCallbackFunction(NULL);
1899  E :  }
1900    :  
1901    :  }  // namespace asan
1902    :  }  // namespace agent

Coverage information generated Wed Dec 11 11:34:16 2013.