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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
60.4%2734520.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_t> 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_t> 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 uint8_t kAllocSize = 13;
  88  E :    ScopedAsanAlloc<uint8_t> 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 (uint8_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  E :    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 (uint8_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 uint8_t kAllocSize = 13;
 114  E :    ScopedAsanAlloc<uint8_t> mem_src(this, kAllocSize);
 115  E :    ASSERT_TRUE(mem_src.get() != NULL);
 116  E :    ScopedAsanAlloc<uint8_t> 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 (uint8_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  E :    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  i :    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  i :    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, AsanCheckStrnlen) {
 226  E :    const char str_value[] = "test_strnlen";
 227  E :    const size_t str_len = arraysize(str_value);
 228  E :    ScopedAsanAlloc<char> str(this, str_len, str_value);
 229  E :    ASSERT_TRUE(str != NULL);
 230    :  
 231  E :    SetCallBackFunction(&AsanErrorCallback);
 232  E :    EXPECT_EQ(::strnlen(str.get(), str_len), strnlenFunction(str.get(), str_len));
 233    :  
 234  E :    strnlenFunctionFailing(str.get() - 1, str_len);
 235  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 236  E :    ResetLog();
 237    :  
 238  E :    size_t n = ::strlen(str.get());
 239  E :    str[n] = 'a';
 240  E :    strnlenFunctionFailing(str.get(), str_len + 1);
 241  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 242  E :    ResetLog();
 243  E :  }
 244    :  
 245  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrrchr) {
 246  E :    const char* str_value = "test_strrchr";
 247  E :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 248  E :    ASSERT_TRUE(str != NULL);
 249    :  
 250  E :    SetCallBackFunction(&AsanErrorCallback);
 251  E :    EXPECT_EQ(::strrchr(str.get(), 'c'), strrchrFunction(str.get(), 'c'));
 252  E :    EXPECT_EQ(::strrchr(str.get(), 'z'), strrchrFunction(str.get(), 'z'));
 253    :  
 254  E :    strrchrFunctionFailing(str.get() - 1, 'c');
 255  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 256  E :    ResetLog();
 257    :  
 258  E :    size_t str_len = ::strlen(str.get());
 259  E :    str[str_len] = 'a';
 260  E :    strrchrFunctionFailing(str.get(), 'c');
 261  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 262  E :    ResetLog();
 263  E :  }
 264    :  
 265  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcsnlen) {
 266  E :    const wchar_t str_value[] = L"test_wcsnlen";
 267  E :    const size_t str_len = arraysize(str_value);
 268  E :    ScopedAsanAlloc<wchar_t> str(this, str_len, str_value);
 269  E :    ASSERT_TRUE(str != NULL);
 270    :  
 271  E :    SetCallBackFunction(&AsanErrorCallback);
 272  E :    EXPECT_EQ(::wcsnlen(str.get(), str_len),
 273  E :              wcsnlenFunction(str.get(), str_len));
 274    :  
 275  E :    wcsnlenFunctionFailing(str.get() - 1, str_len);
 276  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 277  E :    ResetLog();
 278    :  
 279  E :    size_t n = ::wcslen(str.get());
 280  E :    str[n] = 'a';
 281  E :    wcsnlenFunctionFailing(str.get(), str_len + 1);
 282  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 283  E :    ResetLog();
 284  E :  }
 285    :  
 286  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcsrchr) {
 287  E :    const wchar_t* wstr_value = L"test_wcsrchr";
 288  E :    ScopedAsanAlloc<wchar_t> wstr(this, ::wcslen(wstr_value) + 1);
 289  E :    ASSERT_TRUE(wstr != NULL);
 290  E :    wcscpy(wstr.get(), wstr_value);
 291    :  
 292  E :    SetCallBackFunction(&AsanErrorCallback);
 293  E :    EXPECT_EQ(::wcsrchr(wstr.get(), L'c'), wcsrchrFunction(wstr.get(), L'c'));
 294  E :    EXPECT_EQ(::wcsrchr(wstr.get(), 'z'), wcsrchrFunction(wstr.get(), 'z'));
 295    :  
 296  E :    wcsrchrFunctionFailing(wstr.get() - 1, L'c');
 297  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 298  E :    ResetLog();
 299    :  
 300  E :    size_t str_len = ::wcslen(wstr_value);
 301  E :    wstr[str_len] = L'a';
 302  E :    wcsrchrFunctionFailing(wstr.get(), L'c');
 303  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 304  E :    ResetLog();
 305  E :  }
 306    :  
 307  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcschr) {
 308  E :    const wchar_t* wstr_value = L"test_wcschr";
 309  E :    ScopedAsanAlloc<wchar_t> wstr(this, ::wcslen(wstr_value) + 1);
 310  E :    ASSERT_TRUE(wstr != NULL);
 311  E :    wcscpy(wstr.get(), wstr_value);
 312    :  
 313  E :    SetCallBackFunction(&AsanErrorCallback);
 314  E :    EXPECT_EQ(::wcschr(wstr.get(), L'c'), wcschrFunction(wstr.get(), L'c'));
 315  E :    EXPECT_EQ(::wcschr(wstr.get(), 'z'), wcschrFunction(wstr.get(), 'z'));
 316    :  
 317  E :    wcschrFunctionFailing(wstr.get() - 1, L'c');
 318  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 319  E :    ResetLog();
 320    :  
 321  E :    size_t str_len = ::wcslen(wstr_value);
 322  E :    wstr[str_len] = L'a';
 323  E :    wcschrFunctionFailing(wstr.get(), L'z');
 324  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 325  E :    ResetLog();
 326  E :  }
 327    :  
 328  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrcmp) {
 329    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 330    :    //     this interceptor has been fixed.
 331  i :    const char* str_value = "test_strcmp";
 332  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 333  i :    ASSERT_TRUE(str.get() != NULL);
 334    :  
 335  i :    const char* keys_value = "strcmp";
 336  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 337  i :    ASSERT_TRUE(keys.get() != NULL);
 338    :  
 339  i :    SetCallBackFunction(&AsanErrorCallback);
 340  i :    EXPECT_EQ(::strcmp(str.get(), keys.get()),
 341  i :              strcmpFunction(str.get(), keys.get()));
 342    :  
 343  i :    strcmpFunctionFailing(str.get() - 1, keys.get());
 344  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 345  i :    ResetLog();
 346    :  
 347  i :    size_t keys_len = ::strlen(keys.get());
 348  i :    keys[keys_len] = 'a';
 349  i :    strcmpFunctionFailing(str.get(), keys.get());
 350  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 351  i :    keys[keys_len] = 0;
 352  i :    ResetLog();
 353  i :  }
 354    :  
 355  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrpbrk) {
 356    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 357    :    //     this interceptor has been fixed.
 358  i :    const char* str_value = "abc1";
 359  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 360  i :    ASSERT_TRUE(str.get() != NULL);
 361    :  
 362  i :    const char* str_value_2 = "abc";
 363  i :    ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
 364  i :    ASSERT_TRUE(str2.get() != NULL);
 365    :  
 366    :    // This should contain at least one value present in |str| but none present
 367    :    // in |str2|.
 368  i :    const char* keys_value = "12";
 369  i :    EXPECT_NE(::strlen(str_value), ::strcspn(str_value, keys_value));
 370  i :    EXPECT_EQ(::strlen(str_value_2), ::strcspn(str_value_2, keys_value));
 371  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 372  i :    ASSERT_TRUE(keys.get() != NULL);
 373    :  
 374  i :    SetCallBackFunction(&AsanErrorCallback);
 375  i :    EXPECT_EQ(::strpbrk(str.get(), keys.get()),
 376  i :              strpbrkFunction(str.get(), keys.get()));
 377    :  
 378  i :    strpbrkFunctionFailing(str.get() - 1, keys.get());
 379  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 380  i :    ResetLog();
 381    :  
 382  i :    size_t keys_len = ::strlen(keys.get());
 383  i :    keys[keys_len] = 'a';
 384  i :    strpbrkFunctionFailing(str.get(), keys.get());
 385  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 386  i :    keys[keys_len] = 0;
 387  i :    ResetLog();
 388    :  
 389    :    // The implementation allows a non null terminated input string if it contains
 390    :    // at least one of the keys, otherwise it'll overflow.
 391    :  
 392  i :    size_t str_len = ::strlen(str.get());
 393  i :    str[str_len] = 'a';
 394  i :    EXPECT_EQ(::strpbrk(str.get(), keys.get()),
 395  i :              strpbrkFunction(str.get(), keys.get()));
 396  i :    str[str_len] = 0;
 397  i :    ResetLog();
 398    :  
 399  i :    size_t str2_len = ::strlen(str2.get());
 400  i :    str2[str2_len] = 'a';
 401  i :    strpbrkFunctionFailing(str2.get(), keys.get());
 402  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 403  i :    str2[str2_len] = 0;
 404  i :    ResetLog();
 405  i :  }
 406    :  
 407  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanStrpbrkImpl) {
 408    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 409    :    //     this interceptor has been fixed.
 410  i :    const char* abcde = "abcde";
 411  i :    const char* empty_string = "";
 412  i :    EXPECT_EQ(strpbrk(abcde, abcde), asan_strpbrk(abcde, abcde));
 413  i :    EXPECT_EQ(strpbrk(abcde, "fgh"), asan_strpbrk(abcde, "fgh"));
 414  i :    EXPECT_EQ(strpbrk(abcde, ""), asan_strpbrk(abcde, ""));
 415  i :    EXPECT_EQ(strpbrk(abcde, "edcba"), asan_strpbrk(abcde, "edcba"));
 416  i :    EXPECT_EQ(strpbrk(abcde, "ed"), asan_strpbrk(abcde, "ed"));
 417  i :    EXPECT_EQ(strpbrk(abcde, "c"), asan_strpbrk(abcde, "c"));
 418  i :    EXPECT_EQ(strpbrk(empty_string, ""), asan_strpbrk(empty_string, ""));
 419  i :    EXPECT_EQ(strpbrk(empty_string, abcde), asan_strpbrk(empty_string, abcde));
 420  i :  }
 421    :  
 422  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrstr) {
 423    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 424    :    //     this interceptor has been fixed.
 425  i :    const char* str_value = "test_strstr";
 426  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 427  i :    ASSERT_TRUE(str != NULL);
 428    :  
 429  i :    const char* keys_value = "strstr";
 430  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 431  i :    ASSERT_TRUE(keys.get() != NULL);
 432    :  
 433  i :    SetCallBackFunction(&AsanErrorCallback);
 434  i :    EXPECT_EQ(::strstr(str.get(), keys.get()),
 435  i :              strstrFunction(str.get(), keys.get()));
 436    :  
 437  i :    strstrFunctionFailing(str.get() - 1, keys.get());
 438  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 439  i :    ResetLog();
 440    :  
 441  i :    size_t keys_len = ::strlen(keys.get());
 442  i :    keys[keys_len] = 'a';
 443  i :    strstrFunctionFailing(str.get(), keys.get());
 444  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 445  i :    keys[keys_len] = 0;
 446  i :    ResetLog();
 447  i :  }
 448    :  
 449  E :  TEST_F(CrtInterceptorsTest, AsanCheckWcsstr) {
 450  E :    const wchar_t* str_value = L"test_wcsstr";
 451  E :    ScopedAsanAlloc<wchar_t> str(this, ::wcslen(str_value) + 1, str_value);
 452  E :    ASSERT_TRUE(str != NULL);
 453    :  
 454  E :    const wchar_t* keys_value = L"wcsstr";
 455  E :    ScopedAsanAlloc<wchar_t> keys(this, ::wcslen(keys_value) + 1, keys_value);
 456  E :    ASSERT_TRUE(keys.get() != NULL);
 457    :  
 458  E :    EXPECT_EQ(::wcsstr(str.get(), keys.get()),
 459  E :              wcsstrFunction(str.get(), keys.get()));
 460    :  
 461  E :    EXPECT_EQ(NULL, wcsstrFunction(str.get(), L"abcd"));
 462    :  
 463  E :    SetCallBackFunction(&AsanErrorCallback);
 464  E :    keys[::wcslen(keys_value)] = L'a';
 465  E :    wcsstrFunctionFailing(str.get(), keys.get());
 466  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 467  E :    keys[::wcslen(keys_value)] = 0;
 468    :  
 469  E :    ResetLog();
 470  E :  }
 471    :  
 472  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanCheckStrspn) {
 473    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 474    :    //     this interceptor has been fixed.
 475  i :    const char* str_value = "123_abc";
 476  i :    ScopedAsanAlloc<char> str(this, ::strlen(str_value) + 1, str_value);
 477  i :    ASSERT_TRUE(str.get() != NULL);
 478    :  
 479  i :    const char* keys_value = "123";
 480  i :    EXPECT_EQ(::strlen(keys_value), ::strspn(str_value, keys_value));
 481  i :    ScopedAsanAlloc<char> keys(this, ::strlen(keys_value) + 1, keys_value);
 482  i :    ASSERT_TRUE(keys.get() != NULL);
 483    :  
 484    :    // The second test string should only contains values present in the keys.
 485  i :    const char* str_value_2 = "12321";
 486  i :    ScopedAsanAlloc<char> str2(this, ::strlen(str_value_2) + 1, str_value_2);
 487  i :    EXPECT_EQ(::strlen(str_value_2), ::strspn(str_value_2, keys_value));
 488  i :    ASSERT_TRUE(str2.get() != NULL);
 489    :  
 490  i :    SetCallBackFunction(&AsanErrorCallback);
 491  i :    EXPECT_EQ(::strspn(str.get(), keys.get()),
 492  i :              strspnFunction(str.get(), keys.get()));
 493    :  
 494  i :    strspnFunctionFailing(str.get() - 1, keys.get());
 495  i :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 496  i :    ResetLog();
 497    :  
 498  i :    size_t keys_len = ::strlen(keys.get());
 499  i :    keys[keys_len] = 'a';
 500  i :    strspnFunctionFailing(str.get(), keys.get());
 501  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 502  i :    keys[keys_len] = 0;
 503  i :    ResetLog();
 504    :  
 505    :    // The implementation allows a non null terminated input string if it doesn't
 506    :    // start with a value contained in the keys, otherwise it'll overflow.
 507    :  
 508  i :    size_t str_len = ::strlen(str.get());
 509  i :    str[str_len] = 'a';
 510  i :    EXPECT_EQ(::strspn(str.get(), keys.get()),
 511  i :              strspnFunction(str.get(), keys.get()));
 512  i :    str[str_len] = 0;
 513  i :    ResetLog();
 514    :  
 515  i :    size_t str2_len = ::strlen(str2.get());
 516  i :    str2[str2_len] = keys[0];
 517  i :    strspnFunctionFailing(str2.get(), keys.get());
 518  i :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 519  i :    str2[str2_len] = 0;
 520  i :    ResetLog();
 521  i :  }
 522    :  
 523  E :  TEST_F(CrtInterceptorsTest, DISABLED_AsanStrspnImpl) {
 524    :    // TODO(sebmarchand): Reactivate this unittest once the implementation of
 525    :    //     this interceptor has been fixed.
 526  i :    EXPECT_EQ(5, asan_strspn("abcde", "abcde"));
 527  i :    EXPECT_EQ(5, asan_strspn("abcde", "edcba"));
 528  i :    EXPECT_EQ(0U, asan_strspn("abcde", ""));
 529  i :    EXPECT_EQ(2, asan_strspn("abcde", "ab"));
 530  i :    EXPECT_EQ(4, asan_strspn("abccde", "abc"));
 531  i :    EXPECT_EQ(2, asan_strspn("abcde", "fghab"));
 532  i :    EXPECT_EQ(3, asan_strspn("abcde", "fagbhc"));
 533  i :    EXPECT_EQ(1, asan_strspn("abcde", "aaa"));
 534  i :    EXPECT_EQ(0U, asan_strspn("abcde", "fgh"));
 535  i :    EXPECT_EQ(0U, asan_strspn("", ""));
 536  i :    EXPECT_EQ(0U, asan_strspn("", "abcde"));
 537  i :  }
 538    :  
 539  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrncpy) {
 540  E :    const char* str_value = "test_strncpy";
 541  E :    ScopedAsanAlloc<char> source(this, ::strlen(str_value) + 1, str_value);
 542  E :    ASSERT_TRUE(source != NULL);
 543    :  
 544  E :    const char* long_str_value = "test_strncpy_long_source";
 545  E :    ScopedAsanAlloc<char> long_source(this, ::strlen(long_str_value) + 1,
 546    :        long_str_value);
 547  E :    ASSERT_TRUE(long_source.get() != NULL);
 548    :  
 549  E :    ScopedAsanAlloc<char> destination(this, ::strlen(str_value) + 1);
 550  E :    ASSERT_TRUE(destination != NULL);
 551    :  
 552  E :    SetCallBackFunction(&AsanErrorCallback);
 553  E :    EXPECT_EQ(destination.get(),
 554    :              strncpyFunction(destination.get(),
 555    :                              source.get(),
 556  E :                              ::strlen(str_value)));
 557    :  
 558    :    // Test an underflow on the source.
 559  E :    strncpyFunctionFailing(destination.get(),
 560    :                           source.get() - 1,
 561    :                           ::strlen(str_value));
 562  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 563  E :    ResetLog();
 564    :  
 565    :    // Test an underflow on the destination.
 566  E :    strncpyFunctionFailing(destination.get() - 1,
 567    :                           source.get(),
 568    :                           ::strlen(str_value));
 569  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 570  E :    ResetLog();
 571    :  
 572    :    // Test an overflow on the destination.
 573  E :    std::vector<uint8_t> original_data(::strlen(long_str_value));
 574  E :    memcpy(&original_data[0], destination.get(), ::strlen(long_str_value));
 575  E :    strncpyFunctionFailing(destination.get(),
 576    :                           long_source.get(),
 577    :                           ::strlen(long_str_value));
 578  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 579  E :    ResetLog();
 580    :  
 581    :    // Another overflow on the destination.
 582  E :    strncpyFunctionFailing(destination.get(),
 583    :                           source.get(),
 584    :                           ::strlen(str_value) + 2);
 585  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 586  E :    ResetLog();
 587    :  
 588    :    // Test an overflow on the source.
 589  E :    size_t source_len = ::strlen(source.get());
 590  E :    source[source_len] = 'a';
 591  E :    strncpyFunctionFailing(destination.get(),
 592    :                           source.get(),
 593    :                           ::strlen(source.get()) + 1);
 594  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 595  E :    source[source_len] = 0;
 596  E :    ResetLog();
 597  E :  }
 598    :  
 599  E :  TEST_F(CrtInterceptorsTest, AsanCheckStrncat) {
 600  E :    const char* prefix_value = "test_";
 601  E :    const char* suffix_value = "strncat";
 602    :    char buffer[64];
 603    :  
 604  E :    ScopedAsanAlloc<char> mem(this,
 605    :        ::strlen(prefix_value) + ::strlen(suffix_value) + 1, prefix_value);
 606  E :    ASSERT_TRUE(mem != NULL);
 607  E :    ::strcpy(buffer, prefix_value);
 608    :  
 609  E :    ScopedAsanAlloc<char> suffix(this, ::strlen(suffix_value) + 1, suffix_value);
 610  E :    ASSERT_TRUE(mem.get() != NULL);
 611    :  
 612  E :    SetCallBackFunction(&AsanErrorCallback);
 613  E :    EXPECT_EQ(mem.get(),
 614  E :        strncatFunction(mem.get(), suffix.get(), ::strlen(suffix_value)));
 615  E :    EXPECT_STRCASEEQ(
 616  E :        ::strncat(buffer, suffix.get(), ::strlen(suffix_value)), mem.get());
 617    :  
 618    :    // Test an underflow on the suffix.
 619  E :    ::strcpy(mem.get(), prefix_value);
 620  E :    ::strcpy(buffer, prefix_value);
 621  E :    strncatFunctionFailing(mem.get(), suffix.get() - 1, ::strlen(suffix_value));
 622  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 623  E :    ResetLog();
 624    :  
 625    :    // Test an underflow on the destination.
 626  E :    ::strcpy(mem.get(), prefix_value);
 627  E :    ::strcpy(buffer, prefix_value);
 628  E :    strncatFunctionFailing(mem.get() - 1, suffix.get(), ::strlen(suffix_value));
 629  E :    EXPECT_TRUE(LogContains(kHeapBufferUnderFlow));
 630  E :    ResetLog();
 631    :  
 632    :    // Test an overflow on the suffix.
 633  E :    size_t suffix_len = ::strlen(suffix.get());
 634  E :    suffix[suffix_len] = 'a';
 635  E :    ::strcpy(mem.get(), prefix_value);
 636  E :    ::strcpy(buffer, prefix_value);
 637  E :    strncatFunctionFailing(mem.get(), suffix.get(), ::strlen(suffix.get()) + 1);
 638  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 639  E :    suffix[suffix_len] = 0;
 640  E :    ResetLog();
 641    :  
 642    :    // Test an overflow on the destination.
 643  E :    ::strcpy(mem.get(), prefix_value);
 644  E :    ::strcpy(buffer, prefix_value);
 645  E :    size_t prefix_len = ::strlen(prefix_value);
 646  E :    mem[prefix_len] = 'a';
 647  E :    buffer[prefix_len] = 'a';
 648  E :    strncatFunctionFailing(mem.get(), suffix.get(), ::strlen(suffix.get()));
 649  E :    EXPECT_TRUE(LogContains(kHeapBufferOverFlow));
 650  E :    mem[prefix_len] = 0;
 651  E :    buffer[prefix_len] = 0;
 652  E :    ResetLog();
 653  E :  }
 654    :  
 655    :  }  // namespace asan
 656    :  }  // namespace agent

Coverage information generated Fri Jul 29 11:00:21 2016.