blob: ba0a10bb885a8db87fa768545f0faf280adf586b [file] [log] [blame]
[email protected]b4b34792014-06-14 08:29:371// 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
aviebe805c2015-12-24 08:20:285#include <stddef.h>
[email protected]b4b34792014-06-14 08:29:376
7#include "base/debug/alias.h"
8#include "base/debug/asan_invalid_access.h"
9#include "base/logging.h"
10#include "base/memory/scoped_ptr.h"
aviebe805c2015-12-24 08:20:2811#include "build/build_config.h"
12
13#if defined(OS_WIN)
14#include <windows.h>
15#endif
[email protected]b4b34792014-06-14 08:29:3716
17namespace base {
18namespace debug {
19
20namespace {
21
[email protected]8b084ec2014-07-31 03:12:0322#if defined(SYZYASAN) && defined(COMPILER_MSVC)
[email protected]acecfcd2014-07-28 18:25:5623// Disable warning C4530: "C++ exception handler used, but unwind semantics are
24// not enabled". We don't want to change the compilation flags just for this
25// test, and no exception should be triggered here, so this warning has no value
26// here.
27#pragma warning(push)
28#pragma warning(disable: 4530)
[email protected]b4b34792014-06-14 08:29:3729// Corrupt a memory block and make sure that the corruption gets detected either
30// when we free it or when another crash happens (if |induce_crash| is set to
31// true).
32NOINLINE void CorruptMemoryBlock(bool induce_crash) {
33 // NOTE(sebmarchand): We intentionally corrupt a memory block here in order to
34 // trigger an Address Sanitizer (ASAN) error report.
35 static const int kArraySize = 5;
36 int* array = new int[kArraySize];
37 // Encapsulate the invalid memory access into a try-catch statement to prevent
38 // this function from being instrumented. This way the underflow won't be
39 // detected but the corruption will (as the allocator will still be hooked).
40 try {
41 // Declares the dummy value as volatile to make sure it doesn't get
42 // optimized away.
43 int volatile dummy = array[-1]--;
44 base::debug::Alias(const_cast<int*>(&dummy));
45 } catch (...) {
46 }
47 if (induce_crash)
48 CHECK(false);
49 delete[] array;
50}
[email protected]acecfcd2014-07-28 18:25:5651#pragma warning(pop)
[email protected]8b084ec2014-07-31 03:12:0352#endif // SYZYASAN && COMPILER_MSVC
[email protected]b4b34792014-06-14 08:29:3753
54} // namespace
55
56#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
57// NOTE(sebmarchand): We intentionally perform some invalid heap access here in
58// order to trigger an AddressSanitizer (ASan) error report.
59
[email protected]acecfcd2014-07-28 18:25:5660static const size_t kArraySize = 5;
[email protected]b4b34792014-06-14 08:29:3761
62void AsanHeapOverflow() {
thakisfdc6e5f2016-02-24 22:12:3763 // Declares the array as volatile to make sure it doesn't get optimized away.
64 scoped_ptr<volatile int[]> array(
65 const_cast<volatile int*>(new int[kArraySize]));
66 int dummy = array[kArraySize];
67 base::debug::Alias(&dummy);
[email protected]b4b34792014-06-14 08:29:3768}
69
70void AsanHeapUnderflow() {
thakisfdc6e5f2016-02-24 22:12:3771 // Declares the array as volatile to make sure it doesn't get optimized away.
72 scoped_ptr<volatile int[]> array(
73 const_cast<volatile int*>(new int[kArraySize]));
[email protected]acecfcd2014-07-28 18:25:5674 // We need to store the underflow address in a temporary variable as trying to
75 // access array[-1] will trigger a warning C4245: "conversion from 'int' to
76 // 'size_t', signed/unsigned mismatch".
thakisfdc6e5f2016-02-24 22:12:3777 volatile int* underflow_address = &array[0] - 1;
78 int dummy = *underflow_address;
79 base::debug::Alias(&dummy);
[email protected]b4b34792014-06-14 08:29:3780}
81
82void AsanHeapUseAfterFree() {
thakisfdc6e5f2016-02-24 22:12:3783 // Declares the array as volatile to make sure it doesn't get optimized away.
84 scoped_ptr<volatile int[]> array(
85 const_cast<volatile int*>(new int[kArraySize]));
86 volatile int* dangling = array.get();
[email protected]b4b34792014-06-14 08:29:3787 array.reset();
thakisfdc6e5f2016-02-24 22:12:3788 int dummy = dangling[kArraySize / 2];
89 base::debug::Alias(&dummy);
[email protected]b4b34792014-06-14 08:29:3790}
91
92#endif // ADDRESS_SANITIZER || SYZYASAN
93
[email protected]8b084ec2014-07-31 03:12:0394#if defined(SYZYASAN) && defined(COMPILER_MSVC)
[email protected]b4b34792014-06-14 08:29:3795void AsanCorruptHeapBlock() {
96 CorruptMemoryBlock(false);
97}
98
99void AsanCorruptHeap() {
100 CorruptMemoryBlock(true);
101}
[email protected]8b084ec2014-07-31 03:12:03102#endif // SYZYASAN && COMPILER_MSVC
[email protected]b4b34792014-06-14 08:29:37103
104} // namespace debug
105} // namespace base