Index: base/debug/asan_invalid_access.cc |
diff --git a/base/debug/asan_invalid_access.cc b/base/debug/asan_invalid_access.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..409a62791f4ae1e13b3f8723ae13bcd22341e69d |
--- /dev/null |
+++ b/base/debug/asan_invalid_access.cc |
@@ -0,0 +1,91 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#if defined(OS_WIN) |
+#include <windows.h> |
+#endif |
+ |
+#include "base/debug/alias.h" |
+#include "base/debug/asan_invalid_access.h" |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+ |
+namespace base { |
+namespace { |
+ |
+#if defined(SYZYASAN) && defined(COMPILER_MSVC) |
+// Corrupt a memory block and make sure that the corruption gets detected either |
+// when we free it or when another crash happen (if |induce_crash| is set to |
Timur Iskhodzhanov
2014/06/05 15:32:09
happens?
Sébastien Marchand
2014/06/05 19:44:34
Done. Sorry for the grammatical nits and thanks fo
|
+// true). |
+NOINLINE void CorruptMemoryBlock(bool induce_crash) { |
+ // NOTE(sebmarchand): We intentionally corrupt a memory block here in order to |
+ // trigger an Address Sanitizer (ASAN) error report. |
+ static const int kArraySize = 5; |
+ int* array = new int[kArraySize]; |
+ // Encapsulate the invalid memory access into a try-catch statement to prevent |
+ // this function from being instrumented. This way the underflow won't be |
+ // detected but the corruption will (as the allocator will still be hooked). |
+ __try { |
+ // Declares the dummy value as volatile to make sure it doesn't get |
+ // optimized away. |
+ int volatile dummy = array[-1]--; |
+ base::debug::Alias(const_cast<int*>(&dummy)); |
+ } __except (EXCEPTION_EXECUTE_HANDLER) { |
+ } |
+ if (induce_crash) |
+ CHECK(false); |
+ delete[] array; |
+} |
+#endif |
+ |
+} // namespace |
+ |
+#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN) |
+// NOTE(sebmarchand): We intentionally perform some invalid heap access here in |
+// order to trigger an Address Sanitizer (ASAN) error report. |
Timur Iskhodzhanov
2014/06/05 15:32:09
ditto
Timur Iskhodzhanov
2014/06/05 15:32:59
that was about
AddressSanitizer (ASan)
Sébastien Marchand
2014/06/05 19:44:33
Done.
Sébastien Marchand
2014/06/05 19:44:34
Done.
|
+ |
+static const int kArraySize = 5; |
+ |
+void AsanHeapOverflow() { |
+ scoped_ptr<int[]> array(new int[kArraySize]); |
+ // Declares the dummy value as volatile to make sure it doesn't get optimized |
+ // away. |
+ int volatile dummy = 0; |
+ dummy = array[kArraySize]; |
+ base::debug::Alias(const_cast<int*>(&dummy)); |
+} |
+ |
+void AsanHeapUnderflow() { |
+ scoped_ptr<int[]> array(new int[kArraySize]); |
+ // Declares the dummy value as volatile to make sure it doesn't get optimized |
+ // away. |
+ int volatile dummy = 0; |
+ dummy = array[-1]; |
+ base::debug::Alias(const_cast<int*>(&dummy)); |
+} |
+ |
+void AsanHeapUseAfterFree() { |
+ scoped_ptr<int[]> array(new int[kArraySize]); |
+ // Declares the dummy value as volatile to make sure it doesn't get optimized |
+ // away. |
+ int volatile dummy = 0; |
+ int* dangling = array.get(); |
+ array.reset(); |
+ dummy = dangling[kArraySize / 2]; |
+ base::debug::Alias(const_cast<int*>(&dummy)); |
+} |
+ |
+#endif // ADDRESS_SANITIZER || SYZYASAN |
+ |
+#if defined(SYZYASAN) && defined(COMPILER_MSVC) |
+void AsanCorruptHeapBlock() { |
+ CorruptMemoryBlock(false); |
+} |
+ |
+void AsanCorruptHeap() { |
+ CorruptMemoryBlock(true); |
+} |
+#endif // SYZYASAN |
+ |
+} // namespace base |