• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)23 NOINLINE 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()52 void 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()61 void 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()70 void 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()84 void AsanCorruptHeapBlock() {
85   CorruptMemoryBlock(false);
86 }
87 
AsanCorruptHeap()88 void AsanCorruptHeap() {
89   CorruptMemoryBlock(true);
90 }
91 #endif  // SYZYASAN
92 
93 }  // namespace debug
94 }  // namespace base
95