Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / base / debug / asan_invalid_access.cc
blobcee21066265c08282c90fc7fe95430f82422870b
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.
5 #if defined(OS_WIN)
6 #include <windows.h>
7 #endif
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"
14 namespace base {
15 namespace debug {
17 namespace {
19 #if defined(SYZYASAN) && defined(COMPILER_MSVC)
20 // Disable warning C4530: "C++ exception handler used, but unwind semantics are
21 // not enabled". We don't want to change the compilation flags just for this
22 // test, and no exception should be triggered here, so this warning has no value
23 // here.
24 #pragma warning(push)
25 #pragma warning(disable: 4530)
26 // Corrupt a memory block and make sure that the corruption gets detected either
27 // when we free it or when another crash happens (if |induce_crash| is set to
28 // true).
29 NOINLINE void CorruptMemoryBlock(bool induce_crash) {
30 // NOTE(sebmarchand): We intentionally corrupt a memory block here in order to
31 // trigger an Address Sanitizer (ASAN) error report.
32 static const int kArraySize = 5;
33 int* array = new int[kArraySize];
34 // Encapsulate the invalid memory access into a try-catch statement to prevent
35 // this function from being instrumented. This way the underflow won't be
36 // detected but the corruption will (as the allocator will still be hooked).
37 try {
38 // Declares the dummy value as volatile to make sure it doesn't get
39 // optimized away.
40 int volatile dummy = array[-1]--;
41 base::debug::Alias(const_cast<int*>(&dummy));
42 } catch (...) {
44 if (induce_crash)
45 CHECK(false);
46 delete[] array;
48 #pragma warning(pop)
49 #endif // SYZYASAN && COMPILER_MSVC
51 } // namespace
53 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
54 // NOTE(sebmarchand): We intentionally perform some invalid heap access here in
55 // order to trigger an AddressSanitizer (ASan) error report.
57 static const size_t kArraySize = 5;
59 void AsanHeapOverflow() {
60 scoped_ptr<int[]> array(new int[kArraySize]);
61 // Declares the dummy value as volatile to make sure it doesn't get optimized
62 // away.
63 int volatile dummy = 0;
64 dummy = array[kArraySize];
65 base::debug::Alias(const_cast<int*>(&dummy));
68 void AsanHeapUnderflow() {
69 scoped_ptr<int[]> array(new int[kArraySize]);
70 // Declares the dummy value as volatile to make sure it doesn't get optimized
71 // away.
72 int volatile dummy = 0;
73 // We need to store the underflow address in a temporary variable as trying to
74 // access array[-1] will trigger a warning C4245: "conversion from 'int' to
75 // 'size_t', signed/unsigned mismatch".
76 int* underflow_address = &array[0] - 1;
77 dummy = *underflow_address;
78 base::debug::Alias(const_cast<int*>(&dummy));
81 void AsanHeapUseAfterFree() {
82 scoped_ptr<int[]> array(new int[kArraySize]);
83 // Declares the dummy value as volatile to make sure it doesn't get optimized
84 // away.
85 int volatile dummy = 0;
86 int* dangling = array.get();
87 array.reset();
88 dummy = dangling[kArraySize / 2];
89 base::debug::Alias(const_cast<int*>(&dummy));
92 #endif // ADDRESS_SANITIZER || SYZYASAN
94 #if defined(SYZYASAN) && defined(COMPILER_MSVC)
95 void AsanCorruptHeapBlock() {
96 CorruptMemoryBlock(false);
99 void AsanCorruptHeap() {
100 CorruptMemoryBlock(true);
102 #endif // SYZYASAN && COMPILER_MSVC
104 } // namespace debug
105 } // namespace base