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.
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"
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
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
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).
38 // Declares the dummy value as volatile to make sure it doesn't get
40 int volatile dummy
= array
[-1]--;
41 base::debug::Alias(const_cast<int*>(&dummy
));
49 #endif // SYZYASAN && COMPILER_MSVC
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
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
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
85 int volatile dummy
= 0;
86 int* dangling
= array
.get();
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