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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
57.8%2344050.C++test

Line-by-line coverage:

   1    :  // Copyright 2014 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 "syzygy/agent/asan/crt_interceptors.h"
  16    :  
  17    :  #include <windows.h>
  18    :  
  19    :  #include "base/bind.h"
  20    :  #include "gtest/gtest.h"
  21    :  #include "syzygy/agent/asan/unittest_util.h"
  22    :  
  23    :  namespace agent {
  24    :  namespace asan {
  25    :  
  26    :  namespace {
  27    :  
  28    :  using testing::ScopedAsanAlloc;
  29    :  
  30    :  typedef testing::TestAsanRtl CrtInterceptorsTest;
  31    :  
  32    :  // An arbitrary size for the buffer we allocate in the different unittests.
  33    :  const size_t kAllocSize = 13;
  34    :  
  35  E :  void AsanErrorCallback(AsanErrorInfo* error_info) {
  36    :    // Our tests should clean up after themselves and not leave any blocks
  37    :    // corrupt.
  38  E :    ASSERT_NE(CORRUPT_BLOCK, error_info->error_type);
  39    :  
  40    :    // Raise an exception to prevent the intercepted function from corrupting
  41    :    // the block. If this error is not handled then this will cause the unittest
  42    :    // to fail.
  43  E :    ::RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, 0);
  44  i :  }
  45    :  
  46    :  }  // namespace
  47    :  
  48  E :  TEST_F(CrtInterceptorsTest, AsanCheckMemset) {
  49  E :    const size_t kAllocSize = 13;
  50  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
  51  E :    ASSERT_TRUE(mem.get() != NULL);
  52  E :    SetCallBackFunction(&AsanErrorCallback);
  53  E :    EXPECT_EQ(mem.get(), memsetFunction(mem.GetAs<void*>(), 0xAA, kAllocSize));
  54  E :    for (size_t i = 0; i < kAllocSize; ++i)
  55  E :      EXPECT_EQ(0xAA, mem[i]);
  56    :  
  57  E :    memsetFunctionFailing(mem.get() - 1, 0xBB, kAllocSize);
  58  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
  59  E :    ResetLog();
  60    :  
  61  E :    memsetFunctionFailing(mem.get(), 0xCC, kAllocSize + 1);
  62  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
  63  E :    ResetLog();
  64  E :  }
  65    :  
  66  E :  TEST_F(CrtInterceptorsTest, AsanCheckMemchr) {
  67  E :    const size_t kAllocSize = 13;
  68  E :    ScopedAsanAlloc<uint8> mem(this, kAllocSize);
  69  E :    ASSERT_TRUE(mem.get() != NULL);
  70  E :    ::memset(mem.get(), 0, kAllocSize);
  71  E :    mem[4] = 0xAA;
  72    :  
  73  E :    SetCallBackFunction(&AsanErrorCallback);
  74  E :    EXPECT_EQ(mem.get() + 4, memchrFunction(mem.get(), mem[4], kAllocSize));
  75  E :    EXPECT_EQ(NULL, memchrFunction(mem.get(), mem[4] + 1, kAllocSize));
  76    :  
  77  E :    memchrFunctionFailing(mem.get() - 1, mem[4], kAllocSize);
  78  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
  79  E :    ResetLog();
  80    :  
  81  E :    memchrFunctionFailing(mem.get() + 1, mem[4], kAllocSize);
  82  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
  83  E :    ResetLog();
  84  E :  }
  85    :  
  86  E :  TEST_F(CrtInterceptorsTest, AsanCheckMemmove) {
  87  E :    const size_t kAllocSize = 13;
  88  E :    ScopedAsanAlloc<uint8> mem_src(this, kAllocSize);
  89  E :    ASSERT_TRUE(mem_src.get() != NULL);
  90    :    // Fill the array with value going from 0 to kAllocSize;
  91  E :    for (size_t i = 0; i < kAllocSize; ++i)
  92  E :      mem_src[i] = i;
  93    :  
  94  E :    SetCallBackFunction(&AsanErrorCallback);
  95    :    // Shift all the value from one index to the right.
  96    :    EXPECT_EQ(mem_src.get() + 1,
  97  E :              memmoveFunction(mem_src.get() + 1, mem_src.get(), kAllocSize - 1));
  98  E :    EXPECT_EQ(0, mem_src[0]);
  99  E :    for (size_t i = 1; i < kAllocSize; ++i)
 100  E :      EXPECT_EQ(i - 1, mem_src[i]);
 101    :  
 102    :    // Re-shift them to the left.
 103  E :    memmoveFunctionFailing(mem_src.get(), mem_src.get() + 1, kAllocSize);
 104  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 105  E :    ResetLog();
 106    :  
 107  E :    memmoveFunctionFailing(mem_src.get() - 1, mem_src.get(), kAllocSize);
 108  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 109  E :    ResetLog();
 110  E :  }
 111    :  
 112  E :  TEST_F(CrtInterceptorsTest, AsanCheckMemcpy) {
 113  E :    const size_t kAllocSize = 13;
 114  E :    ScopedAsanAlloc<uint8> mem_src(this, kAllocSize);
 115  E :    ASSERT_TRUE(mem_src.get() != NULL);
 116  E :    ScopedAsanAlloc<uint8> mem_dst(this, kAllocSize);
 117  E :    ASSERT_TRUE(mem_dst.get() != NULL);
 118    :    // Fill the array with value going from 0 to kAllocSize;
 119  E :    for (size_t i = 0; i < kAllocSize; ++i) {
 120  E :      mem_src[i] = i;
 121  E :      mem_dst[i] = ~i;
 122  E :    }
 123    :  
 124  E :    SetCallBackFunction(&AsanErrorCallback);
 125    :    EXPECT_EQ(mem_dst.get(),
 126  E :              memcpyFunction(mem_dst.get(), mem_src.get(), kAllocSize));
 127  E :    for (size_t i = 0; i < kAllocSize; ++i)
 128  E :      EXPECT_EQ(mem_dst[i], mem_src[i]);
 129    :  
 130  E :    memcpyFunctionFailing(mem_dst.get(), mem_src.get(), kAllocSize + 1);
 131  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 132  E :    ResetLog();
 133    :  
 134  E :    memcpyFunctionFailing(mem_dst.get(), mem_src.get() - 1, kAllocSize);
 135  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 136  E :    ResetLog();
 137  E :  }
 138    :  
 139  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrcspn) {
 140    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 141    :    //     this interceptor has been fixed.
 142  i :    const char* str_value = "abc1";
 143  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 144  i :    ASSERT_TRUE(str.get() != NULL);
 145    :  
 146  i :    const char* str_value_2 = "abc";
 147  i :    ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
 148  i :    ASSERT_TRUE(str2.get() != NULL);
 149    :  
 150    :    // This should contain at least one value present in |str| but none present
 151    :    // in |str2|.
 152  i :    const char* keys_value = "12";
 153  i :    EXPECT_NE(::strlen(str_value), ::strcspn(str_value, keys_value));
 154  i :    EXPECT_EQ(::strlen(str_value_2), ::strcspn(str_value_2, keys_value));
 155  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 156  i :    ASSERT_TRUE(keys.get() != NULL);
 157    :  
 158  i :    SetCallBackFunction(&AsanErrorCallback);
 159    :    EXPECT_EQ(::strcspn(str.get(), keys.get()),
 160  i :              strcspnFunction(str.get(), keys.get()));
 161    :  
 162  i :    strcspnFunctionFailing(str.get() - 1, keys.get());
 163  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 164  i :    ResetLog();
 165    :  
 166    :    // The key set should be null terminated, otherwise an overflow should be
 167    :    // detected.
 168  i :    size_t keys_len = ::strlen(keys.get());
 169  i :    keys[keys_len] = 'a';
 170  i :    strcspnFunctionFailing(str.get(), keys.get());
 171  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 172  i :    keys[keys_len] = 0;
 173  i :    ResetLog();
 174    :  
 175    :    // The implementation allows a non null terminated input string if it contains
 176    :    // at least one of the keys, otherwise it'll overflow.
 177    :  
 178  i :    size_t str_len = ::strlen(str.get());
 179  i :    str[str_len] = 'a';
 180    :    EXPECT_EQ(::strcspn(str.get(), keys.get()),
 181  i :              strcspnFunction(str.get(), keys.get()));
 182  i :    str[str_len] = 0;
 183  i :    ResetLog();
 184    :  
 185  i :    size_t str2_len = ::strlen(str2.get());
 186  i :    str2[str2_len] = 'a';
 187  i :    strcspnFunctionFailing(str2.get(), keys.get());
 188  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 189  i :    str2[str2_len] = 0;
 190  i :    ResetLog();
 191  i :  }
 192    :  
 193  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanStrcspnImpl) {
 194    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 195    :    //     this interceptor has been fixed.
 196  i :    EXPECT_EQ(5, asan_strcspn("abcde", "fgh"));
 197  i :    EXPECT_EQ(5, asan_strcspn("abcde", ""));
 198  i :    EXPECT_EQ(0, asan_strcspn("abcde", "abcde"));
 199  i :    EXPECT_EQ(0U, asan_strcspn("abcde", "edcba"));
 200  i :    EXPECT_EQ(3, asan_strcspn("abcde", "ed"));
 201  i :    EXPECT_EQ(2, asan_strcspn("abcde", "c"));
 202  i :    EXPECT_EQ(0U, asan_strcspn("", ""));
 203  i :    EXPECT_EQ(0U, asan_strcspn("", "abcde"));
 204  i :  }
 205    :  
 206  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrlen) {
 207  E :    const char* str_value = "test_strlen";
 208  E :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 209  E :    ASSERT_TRUE(str != NULL);
 210    :  
 211  E :    SetCallBackFunction(&AsanErrorCallback);
 212  E :    EXPECT_EQ(::strlen(str.get()), strlenFunction(str.get()));
 213    :  
 214  E :    strlenFunctionFailing(str.get() - 1);
 215  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 216  E :    ResetLog();
 217    :  
 218  E :    size_t str_len = ::strlen(str.get());
 219  E :    str[str_len] = 'a';
 220  E :    strlenFunctionFailing(str.get());
 221  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 222  E :    ResetLog();
 223  E :  }
 224    :  
 225  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrrchr) {
 226  E :    const char* str_value = "test_strrchr";
 227  E :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 228  E :    ASSERT_TRUE(str != NULL);
 229    :  
 230  E :    SetCallBackFunction(&AsanErrorCallback);
 231  E :    EXPECT_EQ(::strrchr(str.get(), 'c'), strrchrFunction(str.get(), 'c'));
 232  E :    EXPECT_EQ(::strrchr(str.get(), 'z'), strrchrFunction(str.get(), 'z'));
 233    :  
 234  E :    strrchrFunctionFailing(str.get() - 1, 'c');
 235  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 236  E :    ResetLog();
 237    :  
 238  E :    size_t str_len = ::strlen(str.get());
 239  E :    str[str_len] = 'a';
 240  E :    strrchrFunctionFailing(str.get(), 'c');
 241  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 242  E :    ResetLog();
 243  E :  }
 244    :  
 245  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcsrchr) {
 246  E :    const wchar_t* wstr_value = L"test_wcsrchr";
 247  E :    ScopedAsanAlloc<wchar_t> wstr(this, ::wcslen(wstr_value) + 1);
 248  E :    ASSERT_TRUE(wstr != NULL);
 249  E :    wcscpy(wstr.get(), wstr_value);
 250    :  
 251  E :    SetCallBackFunction(&AsanErrorCallback);
 252  E :    EXPECT_EQ(::wcsrchr(wstr.get(), L'c'), wcsrchrFunction(wstr.get(), L'c'));
 253  E :    EXPECT_EQ(::wcsrchr(wstr.get(), 'z'), wcsrchrFunction(wstr.get(), 'z'));
 254    :  
 255  E :    wcsrchrFunctionFailing(wstr.get() - 1, L'c');
 256  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 257  E :    ResetLog();
 258    :  
 259  E :    size_t str_len = ::wcslen(wstr_value);
 260  E :    wstr[str_len] = L'a';
 261  E :    wcsrchrFunctionFailing(wstr.get(), L'c');
 262  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 263  E :    ResetLog();
 264  E :  }
 265    :  
 266  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcschr) {
 267  E :    const wchar_t* wstr_value = L"test_wcschr";
 268  E :    ScopedAsanAlloc<wchar_t> wstr(this, ::wcslen(wstr_value) + 1);
 269  E :    ASSERT_TRUE(wstr != NULL);
 270  E :    wcscpy(wstr.get(), wstr_value);
 271    :  
 272  E :    SetCallBackFunction(&AsanErrorCallback);
 273  E :    EXPECT_EQ(::wcschr(wstr.get(), L'c'), wcschrFunction(wstr.get(), L'c'));
 274  E :    EXPECT_EQ(::wcschr(wstr.get(), 'z'), wcschrFunction(wstr.get(), 'z'));
 275    :  
 276  E :    wcschrFunctionFailing(wstr.get() - 1, L'c');
 277  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 278  E :    ResetLog();
 279    :  
 280  E :    size_t str_len = ::wcslen(wstr_value);
 281  E :    wstr[str_len] = L'a';
 282  E :    wcschrFunctionFailing(wstr.get(), L'z');
 283  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 284  E :    ResetLog();
 285  E :  }
 286    :  
 287  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrcmp) {
 288    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 289    :    //     this interceptor has been fixed.
 290  i :    const char* str_value = "test_strcmp";
 291  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 292  i :    ASSERT_TRUE(str.get() != NULL);
 293    :  
 294  i :    const char* keys_value = "strcmp";
 295  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 296  i :    ASSERT_TRUE(keys.get() != NULL);
 297    :  
 298  i :    SetCallBackFunction(&AsanErrorCallback);
 299    :    EXPECT_EQ(::strcmp(str.get(), keys.get()),
 300  i :              strcmpFunction(str.get(), keys.get()));
 301    :  
 302  i :    strcmpFunctionFailing(str.get() - 1, keys.get());
 303  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 304  i :    ResetLog();
 305    :  
 306  i :    size_t keys_len = ::strlen(keys.get());
 307  i :    keys[keys_len] = 'a';
 308  i :    strcmpFunctionFailing(str.get(), keys.get());
 309  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 310  i :    keys[keys_len] = 0;
 311  i :    ResetLog();
 312  i :  }
 313    :  
 314  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrpbrk) {
 315    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 316    :    //     this interceptor has been fixed.
 317  i :    const char* str_value = "abc1";
 318  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 319  i :    ASSERT_TRUE(str.get() != NULL);
 320    :  
 321  i :    const char* str_value_2 = "abc";
 322  i :    ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
 323  i :    ASSERT_TRUE(str2.get() != NULL);
 324    :  
 325    :    // This should contain at least one value present in |str| but none present
 326    :    // in |str2|.
 327  i :    const char* keys_value = "12";
 328  i :    EXPECT_NE(::strlen(str_value), ::strcspn(str_value, keys_value));
 329  i :    EXPECT_EQ(::strlen(str_value_2), ::strcspn(str_value_2, keys_value));
 330  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 331  i :    ASSERT_TRUE(keys.get() != NULL);
 332    :  
 333  i :    SetCallBackFunction(&AsanErrorCallback);
 334    :    EXPECT_EQ(::strpbrk(str.get(), keys.get()),
 335  i :              strpbrkFunction(str.get(), keys.get()));
 336    :  
 337  i :    strpbrkFunctionFailing(str.get() - 1, keys.get());
 338  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 339  i :    ResetLog();
 340    :  
 341  i :    size_t keys_len = ::strlen(keys.get());
 342  i :    keys[keys_len] = 'a';
 343  i :    strpbrkFunctionFailing(str.get(), keys.get());
 344  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 345  i :    keys[keys_len] = 0;
 346  i :    ResetLog();
 347    :  
 348    :    // The implementation allows a non null terminated input string if it contains
 349    :    // at least one of the keys, otherwise it'll overflow.
 350    :  
 351  i :    size_t str_len = ::strlen(str.get());
 352  i :    str[str_len] = 'a';
 353    :    EXPECT_EQ(::strpbrk(str.get(), keys.get()),
 354  i :              strpbrkFunction(str.get(), keys.get()));
 355  i :    str[str_len] = 0;
 356  i :    ResetLog();
 357    :  
 358  i :    size_t str2_len = ::strlen(str2.get());
 359  i :    str2[str2_len] = 'a';
 360  i :    strpbrkFunctionFailing(str2.get(), keys.get());
 361  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 362  i :    str2[str2_len] = 0;
 363  i :    ResetLog();
 364  i :  }
 365    :  
 366  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanStrpbrkImpl) {
 367    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 368    :    //     this interceptor has been fixed.
 369  i :    const char* abcde = "abcde";
 370  i :    const char* empty_string = "";
 371  i :    EXPECT_EQ(strpbrk(abcde, abcde), asan_strpbrk(abcde, abcde));
 372  i :    EXPECT_EQ(strpbrk(abcde, "fgh"), asan_strpbrk(abcde, "fgh"));
 373  i :    EXPECT_EQ(strpbrk(abcde, ""), asan_strpbrk(abcde, ""));
 374  i :    EXPECT_EQ(strpbrk(abcde, "edcba"), asan_strpbrk(abcde, "edcba"));
 375  i :    EXPECT_EQ(strpbrk(abcde, "ed"), asan_strpbrk(abcde, "ed"));
 376  i :    EXPECT_EQ(strpbrk(abcde, "c"), asan_strpbrk(abcde, "c"));
 377  i :    EXPECT_EQ(strpbrk(empty_string, ""), asan_strpbrk(empty_string, ""));
 378  i :    EXPECT_EQ(strpbrk(empty_string, abcde), asan_strpbrk(empty_string, abcde));
 379  i :  }
 380    :  
 381  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrstr) {
 382    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 383    :    //     this interceptor has been fixed.
 384  i :    const char* str_value = "test_strstr";
 385  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 386  i :    ASSERT_TRUE(str != NULL);
 387    :  
 388  i :    const char* keys_value = "strstr";
 389  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 390  i :    ASSERT_TRUE(keys.get() != NULL);
 391    :  
 392  i :    SetCallBackFunction(&AsanErrorCallback);
 393    :    EXPECT_EQ(::strstr(str.get(), keys.get()),
 394  i :              strstrFunction(str.get(), keys.get()));
 395    :  
 396  i :    strstrFunctionFailing(str.get() - 1, keys.get());
 397  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 398  i :    ResetLog();
 399    :  
 400  i :    size_t keys_len = ::strlen(keys.get());
 401  i :    keys[keys_len] = 'a';
 402  i :    strstrFunctionFailing(str.get(), keys.get());
 403  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 404  i :    keys[keys_len] = 0;
 405  i :    ResetLog();
 406  i :  }
 407    :  
 408  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcsstr) {
 409  E :    const wchar_t* str_value = L"test_wcsstr";
 410  E :    ScopedAsanAlloc<wchar_t> str(this, ::wcslen(str_value) + 1, str_value);
 411  E :    ASSERT_TRUE(str != NULL);
 412    :  
 413  E :    const wchar_t* keys_value = L"wcsstr";
 414  E :    ScopedAsanAlloc<wchar_t> keys(this, ::wcslen(keys_value) + 1, keys_value);
 415  E :    ASSERT_TRUE(keys.get() != NULL);
 416    :  
 417    :    EXPECT_EQ(::wcsstr(str.get(), keys.get()),
 418  E :              wcsstrFunction(str.get(), keys.get()));
 419    :  
 420  E :    EXPECT_EQ(NULL, wcsstrFunction(str.get(), L"abcd"));
 421    :  
 422  E :    SetCallBackFunction(&AsanErrorCallback);
 423  E :    keys[::wcslen(keys_value)] = L'a';
 424  E :    wcsstrFunctionFailing(str.get(), keys.get());
 425  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 426  E :    keys[::wcslen(keys_value)] = 0;
 427    :  
 428  E :    ResetLog();
 429  E :  }
 430    :  
 431  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrspn) {
 432    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 433    :    //     this interceptor has been fixed.
 434  i :    const char* str_value = "123_abc";
 435  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 436  i :    ASSERT_TRUE(str.get() != NULL);
 437    :  
 438  i :    const char* keys_value = "123";
 439  i :    EXPECT_EQ(::strlen(keys_value), ::strspn(str_value, keys_value));
 440  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 441  i :    ASSERT_TRUE(keys.get() != NULL);
 442    :  
 443    :    // The second test string should only contains values present in the keys.
 444  i :    const char* str_value_2 = "12321";
 445  i :    ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
 446  i :    EXPECT_EQ(::strlen(str_value_2), ::strspn(str_value_2, keys_value));
 447  i :    ASSERT_TRUE(str2.get() != NULL);
 448    :  
 449  i :    SetCallBackFunction(&AsanErrorCallback);
 450    :    EXPECT_EQ(::strspn(str.get(), keys.get()),
 451  i :              strspnFunction(str.get(), keys.get()));
 452    :  
 453  i :    strspnFunctionFailing(str.get() - 1, keys.get());
 454  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 455  i :    ResetLog();
 456    :  
 457  i :    size_t keys_len = ::strlen(keys.get());
 458  i :    keys[keys_len] = 'a';
 459  i :    strspnFunctionFailing(str.get(), keys.get());
 460  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 461  i :    keys[keys_len] = 0;
 462  i :    ResetLog();
 463    :  
 464    :    // The implementation allows a non null terminated input string if it doesn't
 465    :    // start with a value contained in the keys, otherwise it'll overflow.
 466    :  
 467  i :    size_t str_len = ::strlen(str.get());
 468  i :    str[str_len] = 'a';
 469    :    EXPECT_EQ(::strspn(str.get(), keys.get()),
 470  i :              strspnFunction(str.get(), keys.get()));
 471  i :    str[str_len] = 0;
 472  i :    ResetLog();
 473    :  
 474  i :    size_t str2_len = ::strlen(str2.get());
 475  i :    str2[str2_len] = keys[0];
 476  i :    strspnFunctionFailing(str2.get(), keys.get());
 477  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 478  i :    str2[str2_len] = 0;
 479  i :    ResetLog();
 480  i :  }
 481    :  
 482  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanStrspnImpl) {
 483    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 484    :    //     this interceptor has been fixed.
 485  i :    EXPECT_EQ(5, asan_strspn("abcde", "abcde"));
 486  i :    EXPECT_EQ(5, asan_strspn("abcde", "edcba"));
 487  i :    EXPECT_EQ(0U, asan_strspn("abcde", ""));
 488  i :    EXPECT_EQ(2, asan_strspn("abcde", "ab"));
 489  i :    EXPECT_EQ(4, asan_strspn("abccde", "abc"));
 490  i :    EXPECT_EQ(2, asan_strspn("abcde", "fghab"));
 491  i :    EXPECT_EQ(3, asan_strspn("abcde", "fagbhc"));
 492  i :    EXPECT_EQ(1, asan_strspn("abcde", "aaa"));
 493  i :    EXPECT_EQ(0U, asan_strspn("abcde", "fgh"));
 494  i :    EXPECT_EQ(0U, asan_strspn("", ""));
 495  i :    EXPECT_EQ(0U, asan_strspn("", "abcde"));
 496  i :  }
 497    :  
 498  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrncpy) {
 499  E :    const char* str_value = "test_strncpy";
 500  E :    ScopedAsanAlloc<char> source(this, ::strlen(str_value) + 1, str_value);
 501  E :    ASSERT_TRUE(source != NULL);
 502    :  
 503  E :    const char* long_str_value = "test_strncpy_long_source";
 504    :    ScopedAsanAlloc<char> long_source(this, ::strlen(long_str_value) + 1,
 505  E :        long_str_value);
 506  E :    ASSERT_TRUE(long_source.get() != NULL);
 507    :  
 508  E :    ScopedAsanAlloc<char> destination(this, ::strlen(str_value) + 1);
 509  E :    ASSERT_TRUE(destination != NULL);
 510    :  
 511  E :    SetCallBackFunction(&AsanErrorCallback);
 512    :    EXPECT_EQ(destination.get(),
 513    :              strncpyFunction(destination.get(),
 514    :                              source.get(),
 515  E :                              ::strlen(str_value)));
 516    :  
 517    :    // Test an underflow on the source.
 518    :    strncpyFunctionFailing(destination.get(),
 519    :                           source.get() - 1,
 520  E :                           ::strlen(str_value));
 521  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 522  E :    ResetLog();
 523    :  
 524    :    // Test an underflow on the destination.
 525    :    strncpyFunctionFailing(destination.get() - 1,
 526    :                           source.get(),
 527  E :                           ::strlen(str_value));
 528  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 529  E :    ResetLog();
 530    :  
 531    :    // Test an overflow on the destination.
 532  E :    std::vector<uint8> original_data(::strlen(long_str_value));
 533  E :    memcpy(&original_data[0], destination.get(), ::strlen(long_str_value));
 534    :    strncpyFunctionFailing(destination.get(),
 535    :                           long_source.get(),
 536  E :                           ::strlen(long_str_value));
 537  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 538  E :    ResetLog();
 539    :  
 540    :    // Another overflow on the destination.
 541    :    strncpyFunctionFailing(destination.get(),
 542    :                           source.get(),
 543  E :                           ::strlen(str_value) + 2);
 544  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 545  E :    ResetLog();
 546    :  
 547    :    // Test an overflow on the source.
 548  E :    size_t source_len = ::strlen(source.get());
 549  E :    source[source_len] = 'a';
 550    :    strncpyFunctionFailing(destination.get(),
 551    :                           source.get(),
 552  E :                           ::strlen(source.get()) + 1);
 553  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 554  E :    source[source_len] = 0;
 555  E :    ResetLog();
 556  E :  }
 557    :  
 558  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrncat) {
 559  E :    const char* prefix_value = "test_";
 560  E :    const char* suffix_value = "strncat";
 561    :    char buffer[64];
 562    :  
 563    :    ScopedAsanAlloc<char> mem(this,
 564  E :        ::strlen(prefix_value) + ::strlen(suffix_value) + 1, prefix_value);
 565  E :    ASSERT_TRUE(mem != NULL);
 566  E :    ::strcpy(buffer, prefix_value);
 567    :  
 568  E :    ScopedAsanAlloc<char> suffix(this, ::strlen(suffix_value) + 1, suffix_value);
 569  E :    ASSERT_TRUE(mem.get() != NULL);
 570    :  
 571  E :    SetCallBackFunction(&AsanErrorCallback);
 572    :    EXPECT_EQ(mem.get(),
 573  E :        strncatFunction(mem.get(), suffix.get(), ::strlen(suffix_value)));
 574    :    EXPECT_STRCASEEQ(
 575  E :        ::strncat(buffer, suffix.get(), ::strlen(suffix_value)), mem.get());
 576    :  
 577    :    // Test an underflow on the suffix.
 578  E :    ::strcpy(mem.get(), prefix_value);
 579  E :    ::strcpy(buffer, prefix_value);
 580  E :    strncatFunctionFailing(mem.get(), suffix.get() - 1, ::strlen(suffix_value));
 581  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 582  E :    ResetLog();
 583    :  
 584    :    // Test an underflow on the destination.
 585  E :    ::strcpy(mem.get(), prefix_value);
 586  E :    ::strcpy(buffer, prefix_value);
 587  E :    strncatFunctionFailing(mem.get() - 1, suffix.get(), ::strlen(suffix_value));
 588  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 589  E :    ResetLog();
 590    :  
 591    :    // Test an overflow on the suffix.
 592  E :    size_t suffix_len = ::strlen(suffix.get());
 593  E :    suffix[suffix_len] = 'a';
 594  E :    ::strcpy(mem.get(), prefix_value);
 595  E :    ::strcpy(buffer, prefix_value);
 596  E :    strncatFunctionFailing(mem.get(), suffix.get(), ::strlen(suffix.get()) + 1);
 597  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 598  E :    suffix[suffix_len] = 0;
 599  E :    ResetLog();
 600    :  
 601    :    // Test an overflow on the destination.
 602  E :    ::strcpy(mem.get(), prefix_value);
 603  E :    ::strcpy(buffer, prefix_value);
 604  E :    size_t prefix_len = ::strlen(prefix_value);
 605  E :    mem[prefix_len] = 'a';
 606  E :    buffer[prefix_len] = 'a';
 607  E :    strncatFunctionFailing(mem.get(), suffix.get(), ::strlen(suffix.get()));
 608  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 609  E :    mem[prefix_len] = 0;
 610  E :    buffer[prefix_len] = 0;
 611  E :    ResetLog();
 612  E :  }
 613    :  
 614    :  }  // namespace asan
 615    :  }  // namespace agent

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