1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #if defined(OS_WIN) 6 #include <windows.h> 7 #endif 8 9 #include "base/debug/alias.h" 10 #include "base/debug/asan_invalid_access.h" 11 #include "base/logging.h" 12 #include "base/memory/scoped_ptr.h" 13 14 namespace base { 15 namespace debug { 16 17 namespace { 18 19 #if defined(SYZYASAN) 20 // Corrupt a memory block and make sure that the corruption gets detected either 21 // when we free it or when another crash happens (if |induce_crash| is set to 22 // true). CorruptMemoryBlock(bool induce_crash)23NOINLINE void CorruptMemoryBlock(bool induce_crash) { 24 // NOTE(sebmarchand): We intentionally corrupt a memory block here in order to 25 // trigger an Address Sanitizer (ASAN) error report. 26 static const int kArraySize = 5; 27 int* array = new int[kArraySize]; 28 // Encapsulate the invalid memory access into a try-catch statement to prevent 29 // this function from being instrumented. This way the underflow won't be 30 // detected but the corruption will (as the allocator will still be hooked). 31 try { 32 // Declares the dummy value as volatile to make sure it doesn't get 33 // optimized away. 34 int volatile dummy = array[-1]--; 35 base::debug::Alias(const_cast<int*>(&dummy)); 36 } catch (...) { 37 } 38 if (induce_crash) 39 CHECK(false); 40 delete[] array; 41 } 42 #endif 43 44 } // namespace 45 46 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN) 47 // NOTE(sebmarchand): We intentionally perform some invalid heap access here in 48 // order to trigger an AddressSanitizer (ASan) error report. 49 50 static const int kArraySize = 5; 51 AsanHeapOverflow()52void AsanHeapOverflow() { 53 scoped_ptr<int[]> array(new int[kArraySize]); 54 // Declares the dummy value as volatile to make sure it doesn't get optimized 55 // away. 56 int volatile dummy = 0; 57 dummy = array[kArraySize]; 58 base::debug::Alias(const_cast<int*>(&dummy)); 59 } 60 AsanHeapUnderflow()61void AsanHeapUnderflow() { 62 scoped_ptr<int[]> array(new int[kArraySize]); 63 // Declares the dummy value as volatile to make sure it doesn't get optimized 64 // away. 65 int volatile dummy = 0; 66 dummy = array[-1]; 67 base::debug::Alias(const_cast<int*>(&dummy)); 68 } 69 AsanHeapUseAfterFree()70void AsanHeapUseAfterFree() { 71 scoped_ptr<int[]> array(new int[kArraySize]); 72 // Declares the dummy value as volatile to make sure it doesn't get optimized 73 // away. 74 int volatile dummy = 0; 75 int* dangling = array.get(); 76 array.reset(); 77 dummy = dangling[kArraySize / 2]; 78 base::debug::Alias(const_cast<int*>(&dummy)); 79 } 80 81 #endif // ADDRESS_SANITIZER || SYZYASAN 82 83 #if defined(SYZYASAN) AsanCorruptHeapBlock()84void AsanCorruptHeapBlock() { 85 CorruptMemoryBlock(false); 86 } 87 AsanCorruptHeap()88void AsanCorruptHeap() { 89 CorruptMemoryBlock(true); 90 } 91 #endif // SYZYASAN 92 93 } // namespace debug 94 } // namespace base 95