1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker //
5*635a8641SAndroid Build Coastguard Worker // This file contains intentional memory errors, some of which may lead to
6*635a8641SAndroid Build Coastguard Worker // crashes if the test is ran without special memory testing tools. We use these
7*635a8641SAndroid Build Coastguard Worker // errors to verify the sanity of the tools.
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include "base/atomicops.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/cfi_buildflags.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/debug/asan_invalid_access.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/debug/profiler.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
17*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
18*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
19*635a8641SAndroid Build Coastguard Worker
20*635a8641SAndroid Build Coastguard Worker namespace base {
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Worker namespace {
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker const base::subtle::Atomic32 kMagicValue = 42;
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard Worker // Helper for memory accesses that can potentially corrupt memory or cause a
27*635a8641SAndroid Build Coastguard Worker // crash during a native run.
28*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
29*635a8641SAndroid Build Coastguard Worker #if defined(OS_IOS)
30*635a8641SAndroid Build Coastguard Worker // EXPECT_DEATH is not supported on IOS.
31*635a8641SAndroid Build Coastguard Worker #define HARMFUL_ACCESS(action,error_regexp) do { action; } while (0)
32*635a8641SAndroid Build Coastguard Worker #else
33*635a8641SAndroid Build Coastguard Worker #define HARMFUL_ACCESS(action,error_regexp) EXPECT_DEATH(action,error_regexp)
34*635a8641SAndroid Build Coastguard Worker #endif // !OS_IOS
35*635a8641SAndroid Build Coastguard Worker #else
36*635a8641SAndroid Build Coastguard Worker #define HARMFUL_ACCESS(action, error_regexp)
37*635a8641SAndroid Build Coastguard Worker #define HARMFUL_ACCESS_IS_NOOP
38*635a8641SAndroid Build Coastguard Worker #endif
39*635a8641SAndroid Build Coastguard Worker
DoReadUninitializedValue(char * ptr)40*635a8641SAndroid Build Coastguard Worker void DoReadUninitializedValue(char *ptr) {
41*635a8641SAndroid Build Coastguard Worker // Comparison with 64 is to prevent clang from optimizing away the
42*635a8641SAndroid Build Coastguard Worker // jump -- valgrind only catches jumps and conditional moves, but clang uses
43*635a8641SAndroid Build Coastguard Worker // the borrow flag if the condition is just `*ptr == '\0'`. We no longer
44*635a8641SAndroid Build Coastguard Worker // support valgrind, but this constant should be fine to keep as-is.
45*635a8641SAndroid Build Coastguard Worker if (*ptr == 64) {
46*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Uninit condition is true";
47*635a8641SAndroid Build Coastguard Worker } else {
48*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Uninit condition is false";
49*635a8641SAndroid Build Coastguard Worker }
50*635a8641SAndroid Build Coastguard Worker }
51*635a8641SAndroid Build Coastguard Worker
ReadUninitializedValue(char * ptr)52*635a8641SAndroid Build Coastguard Worker void ReadUninitializedValue(char *ptr) {
53*635a8641SAndroid Build Coastguard Worker #if defined(MEMORY_SANITIZER)
54*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH(DoReadUninitializedValue(ptr),
55*635a8641SAndroid Build Coastguard Worker "use-of-uninitialized-value");
56*635a8641SAndroid Build Coastguard Worker #else
57*635a8641SAndroid Build Coastguard Worker DoReadUninitializedValue(ptr);
58*635a8641SAndroid Build Coastguard Worker #endif
59*635a8641SAndroid Build Coastguard Worker }
60*635a8641SAndroid Build Coastguard Worker
61*635a8641SAndroid Build Coastguard Worker #ifndef HARMFUL_ACCESS_IS_NOOP
ReadValueOutOfArrayBoundsLeft(char * ptr)62*635a8641SAndroid Build Coastguard Worker void ReadValueOutOfArrayBoundsLeft(char *ptr) {
63*635a8641SAndroid Build Coastguard Worker char c = ptr[-2];
64*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Reading a byte out of bounds: " << c;
65*635a8641SAndroid Build Coastguard Worker }
66*635a8641SAndroid Build Coastguard Worker
ReadValueOutOfArrayBoundsRight(char * ptr,size_t size)67*635a8641SAndroid Build Coastguard Worker void ReadValueOutOfArrayBoundsRight(char *ptr, size_t size) {
68*635a8641SAndroid Build Coastguard Worker char c = ptr[size + 1];
69*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Reading a byte out of bounds: " << c;
70*635a8641SAndroid Build Coastguard Worker }
71*635a8641SAndroid Build Coastguard Worker
WriteValueOutOfArrayBoundsLeft(char * ptr)72*635a8641SAndroid Build Coastguard Worker void WriteValueOutOfArrayBoundsLeft(char *ptr) {
73*635a8641SAndroid Build Coastguard Worker ptr[-1] = kMagicValue;
74*635a8641SAndroid Build Coastguard Worker }
75*635a8641SAndroid Build Coastguard Worker
WriteValueOutOfArrayBoundsRight(char * ptr,size_t size)76*635a8641SAndroid Build Coastguard Worker void WriteValueOutOfArrayBoundsRight(char *ptr, size_t size) {
77*635a8641SAndroid Build Coastguard Worker ptr[size] = kMagicValue;
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker #endif // HARMFUL_ACCESS_IS_NOOP
80*635a8641SAndroid Build Coastguard Worker
MakeSomeErrors(char * ptr,size_t size)81*635a8641SAndroid Build Coastguard Worker void MakeSomeErrors(char *ptr, size_t size) {
82*635a8641SAndroid Build Coastguard Worker ReadUninitializedValue(ptr);
83*635a8641SAndroid Build Coastguard Worker
84*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(ReadValueOutOfArrayBoundsLeft(ptr),
85*635a8641SAndroid Build Coastguard Worker "2 bytes to the left");
86*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(ReadValueOutOfArrayBoundsRight(ptr, size),
87*635a8641SAndroid Build Coastguard Worker "1 bytes to the right");
88*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(WriteValueOutOfArrayBoundsLeft(ptr),
89*635a8641SAndroid Build Coastguard Worker "1 bytes to the left");
90*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(WriteValueOutOfArrayBoundsRight(ptr, size),
91*635a8641SAndroid Build Coastguard Worker "0 bytes to the right");
92*635a8641SAndroid Build Coastguard Worker }
93*635a8641SAndroid Build Coastguard Worker
94*635a8641SAndroid Build Coastguard Worker } // namespace
95*635a8641SAndroid Build Coastguard Worker
96*635a8641SAndroid Build Coastguard Worker // A memory leak detector should report an error in this test.
TEST(ToolsSanityTest,MemoryLeak)97*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, MemoryLeak) {
98*635a8641SAndroid Build Coastguard Worker // Without the |volatile|, clang optimizes away the next two lines.
99*635a8641SAndroid Build Coastguard Worker int* volatile leak = new int[256]; // Leak some memory intentionally.
100*635a8641SAndroid Build Coastguard Worker leak[4] = 1; // Make sure the allocated memory is used.
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker
103*635a8641SAndroid Build Coastguard Worker #if (defined(ADDRESS_SANITIZER) && defined(OS_IOS))
104*635a8641SAndroid Build Coastguard Worker // Because iOS doesn't support death tests, each of the following tests will
105*635a8641SAndroid Build Coastguard Worker // crash the whole program under Asan.
106*635a8641SAndroid Build Coastguard Worker #define MAYBE_AccessesToNewMemory DISABLED_AccessesToNewMemory
107*635a8641SAndroid Build Coastguard Worker #define MAYBE_AccessesToMallocMemory DISABLED_AccessesToMallocMemory
108*635a8641SAndroid Build Coastguard Worker #else
109*635a8641SAndroid Build Coastguard Worker #define MAYBE_AccessesToNewMemory AccessesToNewMemory
110*635a8641SAndroid Build Coastguard Worker #define MAYBE_AccessesToMallocMemory AccessesToMallocMemory
111*635a8641SAndroid Build Coastguard Worker #endif // (defined(ADDRESS_SANITIZER) && defined(OS_IOS))
112*635a8641SAndroid Build Coastguard Worker
113*635a8641SAndroid Build Coastguard Worker // The following tests pass with Clang r170392, but not r172454, which
114*635a8641SAndroid Build Coastguard Worker // makes AddressSanitizer detect errors in them. We disable these tests under
115*635a8641SAndroid Build Coastguard Worker // AddressSanitizer until we fully switch to Clang r172454. After that the
116*635a8641SAndroid Build Coastguard Worker // tests should be put back under the (defined(OS_IOS) || defined(OS_WIN))
117*635a8641SAndroid Build Coastguard Worker // clause above.
118*635a8641SAndroid Build Coastguard Worker // See also http://crbug.com/172614.
119*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
120*635a8641SAndroid Build Coastguard Worker #define MAYBE_SingleElementDeletedWithBraces \
121*635a8641SAndroid Build Coastguard Worker DISABLED_SingleElementDeletedWithBraces
122*635a8641SAndroid Build Coastguard Worker #define MAYBE_ArrayDeletedWithoutBraces DISABLED_ArrayDeletedWithoutBraces
123*635a8641SAndroid Build Coastguard Worker #else
124*635a8641SAndroid Build Coastguard Worker #define MAYBE_ArrayDeletedWithoutBraces ArrayDeletedWithoutBraces
125*635a8641SAndroid Build Coastguard Worker #define MAYBE_SingleElementDeletedWithBraces SingleElementDeletedWithBraces
126*635a8641SAndroid Build Coastguard Worker #endif // defined(ADDRESS_SANITIZER)
127*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,MAYBE_AccessesToNewMemory)128*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, MAYBE_AccessesToNewMemory) {
129*635a8641SAndroid Build Coastguard Worker char *foo = new char[10];
130*635a8641SAndroid Build Coastguard Worker MakeSomeErrors(foo, 10);
131*635a8641SAndroid Build Coastguard Worker delete [] foo;
132*635a8641SAndroid Build Coastguard Worker // Use after delete.
133*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(foo[5] = 0, "heap-use-after-free");
134*635a8641SAndroid Build Coastguard Worker }
135*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,MAYBE_AccessesToMallocMemory)136*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, MAYBE_AccessesToMallocMemory) {
137*635a8641SAndroid Build Coastguard Worker char *foo = reinterpret_cast<char*>(malloc(10));
138*635a8641SAndroid Build Coastguard Worker MakeSomeErrors(foo, 10);
139*635a8641SAndroid Build Coastguard Worker free(foo);
140*635a8641SAndroid Build Coastguard Worker // Use after free.
141*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(foo[5] = 0, "heap-use-after-free");
142*635a8641SAndroid Build Coastguard Worker }
143*635a8641SAndroid Build Coastguard Worker
144*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
145*635a8641SAndroid Build Coastguard Worker
allocateArray()146*635a8641SAndroid Build Coastguard Worker static int* allocateArray() {
147*635a8641SAndroid Build Coastguard Worker // Clang warns about the mismatched new[]/delete if they occur in the same
148*635a8641SAndroid Build Coastguard Worker // function.
149*635a8641SAndroid Build Coastguard Worker return new int[10];
150*635a8641SAndroid Build Coastguard Worker }
151*635a8641SAndroid Build Coastguard Worker
152*635a8641SAndroid Build Coastguard Worker // This test may corrupt memory if not compiled with AddressSanitizer.
TEST(ToolsSanityTest,MAYBE_ArrayDeletedWithoutBraces)153*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, MAYBE_ArrayDeletedWithoutBraces) {
154*635a8641SAndroid Build Coastguard Worker // Without the |volatile|, clang optimizes away the next two lines.
155*635a8641SAndroid Build Coastguard Worker int* volatile foo = allocateArray();
156*635a8641SAndroid Build Coastguard Worker delete foo;
157*635a8641SAndroid Build Coastguard Worker }
158*635a8641SAndroid Build Coastguard Worker #endif
159*635a8641SAndroid Build Coastguard Worker
160*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
allocateScalar()161*635a8641SAndroid Build Coastguard Worker static int* allocateScalar() {
162*635a8641SAndroid Build Coastguard Worker // Clang warns about the mismatched new/delete[] if they occur in the same
163*635a8641SAndroid Build Coastguard Worker // function.
164*635a8641SAndroid Build Coastguard Worker return new int;
165*635a8641SAndroid Build Coastguard Worker }
166*635a8641SAndroid Build Coastguard Worker
167*635a8641SAndroid Build Coastguard Worker // This test may corrupt memory if not compiled with AddressSanitizer.
TEST(ToolsSanityTest,MAYBE_SingleElementDeletedWithBraces)168*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, MAYBE_SingleElementDeletedWithBraces) {
169*635a8641SAndroid Build Coastguard Worker // Without the |volatile|, clang optimizes away the next two lines.
170*635a8641SAndroid Build Coastguard Worker int* volatile foo = allocateScalar();
171*635a8641SAndroid Build Coastguard Worker (void) foo;
172*635a8641SAndroid Build Coastguard Worker delete [] foo;
173*635a8641SAndroid Build Coastguard Worker }
174*635a8641SAndroid Build Coastguard Worker #endif
175*635a8641SAndroid Build Coastguard Worker
176*635a8641SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
177*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,DISABLED_AddressSanitizerNullDerefCrashTest)178*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, DISABLED_AddressSanitizerNullDerefCrashTest) {
179*635a8641SAndroid Build Coastguard Worker // Intentionally crash to make sure AddressSanitizer is running.
180*635a8641SAndroid Build Coastguard Worker // This test should not be ran on bots.
181*635a8641SAndroid Build Coastguard Worker int* volatile zero = NULL;
182*635a8641SAndroid Build Coastguard Worker *zero = 0;
183*635a8641SAndroid Build Coastguard Worker }
184*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,DISABLED_AddressSanitizerLocalOOBCrashTest)185*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, DISABLED_AddressSanitizerLocalOOBCrashTest) {
186*635a8641SAndroid Build Coastguard Worker // Intentionally crash to make sure AddressSanitizer is instrumenting
187*635a8641SAndroid Build Coastguard Worker // the local variables.
188*635a8641SAndroid Build Coastguard Worker // This test should not be ran on bots.
189*635a8641SAndroid Build Coastguard Worker int array[5];
190*635a8641SAndroid Build Coastguard Worker // Work around the OOB warning reported by Clang.
191*635a8641SAndroid Build Coastguard Worker int* volatile access = &array[5];
192*635a8641SAndroid Build Coastguard Worker *access = 43;
193*635a8641SAndroid Build Coastguard Worker }
194*635a8641SAndroid Build Coastguard Worker
195*635a8641SAndroid Build Coastguard Worker namespace {
196*635a8641SAndroid Build Coastguard Worker int g_asan_test_global_array[10];
197*635a8641SAndroid Build Coastguard Worker } // namespace
198*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,DISABLED_AddressSanitizerGlobalOOBCrashTest)199*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, DISABLED_AddressSanitizerGlobalOOBCrashTest) {
200*635a8641SAndroid Build Coastguard Worker // Intentionally crash to make sure AddressSanitizer is instrumenting
201*635a8641SAndroid Build Coastguard Worker // the global variables.
202*635a8641SAndroid Build Coastguard Worker // This test should not be ran on bots.
203*635a8641SAndroid Build Coastguard Worker
204*635a8641SAndroid Build Coastguard Worker // Work around the OOB warning reported by Clang.
205*635a8641SAndroid Build Coastguard Worker int* volatile access = g_asan_test_global_array - 1;
206*635a8641SAndroid Build Coastguard Worker *access = 43;
207*635a8641SAndroid Build Coastguard Worker }
208*635a8641SAndroid Build Coastguard Worker
209*635a8641SAndroid Build Coastguard Worker #ifndef HARMFUL_ACCESS_IS_NOOP
TEST(ToolsSanityTest,AsanHeapOverflow)210*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, AsanHeapOverflow) {
211*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(debug::AsanHeapOverflow() ,"to the right");
212*635a8641SAndroid Build Coastguard Worker }
213*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,AsanHeapUnderflow)214*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, AsanHeapUnderflow) {
215*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(debug::AsanHeapUnderflow(), "to the left");
216*635a8641SAndroid Build Coastguard Worker }
217*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,AsanHeapUseAfterFree)218*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, AsanHeapUseAfterFree) {
219*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(debug::AsanHeapUseAfterFree(), "heap-use-after-free");
220*635a8641SAndroid Build Coastguard Worker }
221*635a8641SAndroid Build Coastguard Worker
222*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
223*635a8641SAndroid Build Coastguard Worker // The ASAN runtime doesn't detect heap corruption, this needs fixing before
224*635a8641SAndroid Build Coastguard Worker // ASAN builds can ship to the wild. See https://crbug.com/818747.
TEST(ToolsSanityTest,DISABLED_AsanCorruptHeapBlock)225*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, DISABLED_AsanCorruptHeapBlock) {
226*635a8641SAndroid Build Coastguard Worker HARMFUL_ACCESS(debug::AsanCorruptHeapBlock(), "");
227*635a8641SAndroid Build Coastguard Worker }
228*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,DISABLED_AsanCorruptHeap)229*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, DISABLED_AsanCorruptHeap) {
230*635a8641SAndroid Build Coastguard Worker // This test will kill the process by raising an exception, there's no
231*635a8641SAndroid Build Coastguard Worker // particular string to look for in the stack trace.
232*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH(debug::AsanCorruptHeap(), "");
233*635a8641SAndroid Build Coastguard Worker }
234*635a8641SAndroid Build Coastguard Worker #endif // OS_WIN
235*635a8641SAndroid Build Coastguard Worker #endif // !HARMFUL_ACCESS_IS_NOOP
236*635a8641SAndroid Build Coastguard Worker
237*635a8641SAndroid Build Coastguard Worker #endif // ADDRESS_SANITIZER
238*635a8641SAndroid Build Coastguard Worker
239*635a8641SAndroid Build Coastguard Worker namespace {
240*635a8641SAndroid Build Coastguard Worker
241*635a8641SAndroid Build Coastguard Worker // We use caps here just to ensure that the method name doesn't interfere with
242*635a8641SAndroid Build Coastguard Worker // the wildcarded suppressions.
243*635a8641SAndroid Build Coastguard Worker class TOOLS_SANITY_TEST_CONCURRENT_THREAD : public PlatformThread::Delegate {
244*635a8641SAndroid Build Coastguard Worker public:
TOOLS_SANITY_TEST_CONCURRENT_THREAD(bool * value)245*635a8641SAndroid Build Coastguard Worker explicit TOOLS_SANITY_TEST_CONCURRENT_THREAD(bool *value) : value_(value) {}
246*635a8641SAndroid Build Coastguard Worker ~TOOLS_SANITY_TEST_CONCURRENT_THREAD() override = default;
ThreadMain()247*635a8641SAndroid Build Coastguard Worker void ThreadMain() override {
248*635a8641SAndroid Build Coastguard Worker *value_ = true;
249*635a8641SAndroid Build Coastguard Worker
250*635a8641SAndroid Build Coastguard Worker // Sleep for a few milliseconds so the two threads are more likely to live
251*635a8641SAndroid Build Coastguard Worker // simultaneously. Otherwise we may miss the report due to mutex
252*635a8641SAndroid Build Coastguard Worker // lock/unlock's inside thread creation code in pure-happens-before mode...
253*635a8641SAndroid Build Coastguard Worker PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
254*635a8641SAndroid Build Coastguard Worker }
255*635a8641SAndroid Build Coastguard Worker private:
256*635a8641SAndroid Build Coastguard Worker bool *value_;
257*635a8641SAndroid Build Coastguard Worker };
258*635a8641SAndroid Build Coastguard Worker
259*635a8641SAndroid Build Coastguard Worker class ReleaseStoreThread : public PlatformThread::Delegate {
260*635a8641SAndroid Build Coastguard Worker public:
ReleaseStoreThread(base::subtle::Atomic32 * value)261*635a8641SAndroid Build Coastguard Worker explicit ReleaseStoreThread(base::subtle::Atomic32 *value) : value_(value) {}
262*635a8641SAndroid Build Coastguard Worker ~ReleaseStoreThread() override = default;
ThreadMain()263*635a8641SAndroid Build Coastguard Worker void ThreadMain() override {
264*635a8641SAndroid Build Coastguard Worker base::subtle::Release_Store(value_, kMagicValue);
265*635a8641SAndroid Build Coastguard Worker
266*635a8641SAndroid Build Coastguard Worker // Sleep for a few milliseconds so the two threads are more likely to live
267*635a8641SAndroid Build Coastguard Worker // simultaneously. Otherwise we may miss the report due to mutex
268*635a8641SAndroid Build Coastguard Worker // lock/unlock's inside thread creation code in pure-happens-before mode...
269*635a8641SAndroid Build Coastguard Worker PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
270*635a8641SAndroid Build Coastguard Worker }
271*635a8641SAndroid Build Coastguard Worker private:
272*635a8641SAndroid Build Coastguard Worker base::subtle::Atomic32 *value_;
273*635a8641SAndroid Build Coastguard Worker };
274*635a8641SAndroid Build Coastguard Worker
275*635a8641SAndroid Build Coastguard Worker class AcquireLoadThread : public PlatformThread::Delegate {
276*635a8641SAndroid Build Coastguard Worker public:
AcquireLoadThread(base::subtle::Atomic32 * value)277*635a8641SAndroid Build Coastguard Worker explicit AcquireLoadThread(base::subtle::Atomic32 *value) : value_(value) {}
278*635a8641SAndroid Build Coastguard Worker ~AcquireLoadThread() override = default;
ThreadMain()279*635a8641SAndroid Build Coastguard Worker void ThreadMain() override {
280*635a8641SAndroid Build Coastguard Worker // Wait for the other thread to make Release_Store
281*635a8641SAndroid Build Coastguard Worker PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
282*635a8641SAndroid Build Coastguard Worker base::subtle::Acquire_Load(value_);
283*635a8641SAndroid Build Coastguard Worker }
284*635a8641SAndroid Build Coastguard Worker private:
285*635a8641SAndroid Build Coastguard Worker base::subtle::Atomic32 *value_;
286*635a8641SAndroid Build Coastguard Worker };
287*635a8641SAndroid Build Coastguard Worker
RunInParallel(PlatformThread::Delegate * d1,PlatformThread::Delegate * d2)288*635a8641SAndroid Build Coastguard Worker void RunInParallel(PlatformThread::Delegate *d1, PlatformThread::Delegate *d2) {
289*635a8641SAndroid Build Coastguard Worker PlatformThreadHandle a;
290*635a8641SAndroid Build Coastguard Worker PlatformThreadHandle b;
291*635a8641SAndroid Build Coastguard Worker PlatformThread::Create(0, d1, &a);
292*635a8641SAndroid Build Coastguard Worker PlatformThread::Create(0, d2, &b);
293*635a8641SAndroid Build Coastguard Worker PlatformThread::Join(a);
294*635a8641SAndroid Build Coastguard Worker PlatformThread::Join(b);
295*635a8641SAndroid Build Coastguard Worker }
296*635a8641SAndroid Build Coastguard Worker
297*635a8641SAndroid Build Coastguard Worker #if defined(THREAD_SANITIZER)
DataRace()298*635a8641SAndroid Build Coastguard Worker void DataRace() {
299*635a8641SAndroid Build Coastguard Worker bool *shared = new bool(false);
300*635a8641SAndroid Build Coastguard Worker TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(shared), thread2(shared);
301*635a8641SAndroid Build Coastguard Worker RunInParallel(&thread1, &thread2);
302*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(*shared);
303*635a8641SAndroid Build Coastguard Worker delete shared;
304*635a8641SAndroid Build Coastguard Worker // We're in a death test - crash.
305*635a8641SAndroid Build Coastguard Worker CHECK(0);
306*635a8641SAndroid Build Coastguard Worker }
307*635a8641SAndroid Build Coastguard Worker #endif
308*635a8641SAndroid Build Coastguard Worker
309*635a8641SAndroid Build Coastguard Worker } // namespace
310*635a8641SAndroid Build Coastguard Worker
311*635a8641SAndroid Build Coastguard Worker #if defined(THREAD_SANITIZER)
312*635a8641SAndroid Build Coastguard Worker // A data race detector should report an error in this test.
TEST(ToolsSanityTest,DataRace)313*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, DataRace) {
314*635a8641SAndroid Build Coastguard Worker // The suppression regexp must match that in base/debug/tsan_suppressions.cc.
315*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH(DataRace(), "1 race:base/tools_sanity_unittest.cc");
316*635a8641SAndroid Build Coastguard Worker }
317*635a8641SAndroid Build Coastguard Worker #endif
318*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,AnnotateBenignRace)319*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, AnnotateBenignRace) {
320*635a8641SAndroid Build Coastguard Worker bool shared = false;
321*635a8641SAndroid Build Coastguard Worker ANNOTATE_BENIGN_RACE(&shared, "Intentional race - make sure doesn't show up");
322*635a8641SAndroid Build Coastguard Worker TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(&shared), thread2(&shared);
323*635a8641SAndroid Build Coastguard Worker RunInParallel(&thread1, &thread2);
324*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(shared);
325*635a8641SAndroid Build Coastguard Worker }
326*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,AtomicsAreIgnored)327*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, AtomicsAreIgnored) {
328*635a8641SAndroid Build Coastguard Worker base::subtle::Atomic32 shared = 0;
329*635a8641SAndroid Build Coastguard Worker ReleaseStoreThread thread1(&shared);
330*635a8641SAndroid Build Coastguard Worker AcquireLoadThread thread2(&shared);
331*635a8641SAndroid Build Coastguard Worker RunInParallel(&thread1, &thread2);
332*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kMagicValue, shared);
333*635a8641SAndroid Build Coastguard Worker }
334*635a8641SAndroid Build Coastguard Worker
335*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(CFI_ENFORCEMENT_TRAP)
336*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
337*635a8641SAndroid Build Coastguard Worker #define CFI_ERROR_MSG "EXCEPTION_ILLEGAL_INSTRUCTION"
338*635a8641SAndroid Build Coastguard Worker #elif defined(OS_ANDROID)
339*635a8641SAndroid Build Coastguard Worker // TODO(pcc): Produce proper stack dumps on Android and test for the correct
340*635a8641SAndroid Build Coastguard Worker // si_code here.
341*635a8641SAndroid Build Coastguard Worker #define CFI_ERROR_MSG "^$"
342*635a8641SAndroid Build Coastguard Worker #else
343*635a8641SAndroid Build Coastguard Worker #define CFI_ERROR_MSG "ILL_ILLOPN"
344*635a8641SAndroid Build Coastguard Worker #endif
345*635a8641SAndroid Build Coastguard Worker #elif BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC)
346*635a8641SAndroid Build Coastguard Worker #define CFI_ERROR_MSG "runtime error: control flow integrity check"
347*635a8641SAndroid Build Coastguard Worker #endif // BUILDFLAG(CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC)
348*635a8641SAndroid Build Coastguard Worker
349*635a8641SAndroid Build Coastguard Worker #if defined(CFI_ERROR_MSG)
350*635a8641SAndroid Build Coastguard Worker class A {
351*635a8641SAndroid Build Coastguard Worker public:
A()352*635a8641SAndroid Build Coastguard Worker A(): n_(0) {}
f()353*635a8641SAndroid Build Coastguard Worker virtual void f() { n_++; }
354*635a8641SAndroid Build Coastguard Worker protected:
355*635a8641SAndroid Build Coastguard Worker int n_;
356*635a8641SAndroid Build Coastguard Worker };
357*635a8641SAndroid Build Coastguard Worker
358*635a8641SAndroid Build Coastguard Worker class B: public A {
359*635a8641SAndroid Build Coastguard Worker public:
f()360*635a8641SAndroid Build Coastguard Worker void f() override { n_--; }
361*635a8641SAndroid Build Coastguard Worker };
362*635a8641SAndroid Build Coastguard Worker
363*635a8641SAndroid Build Coastguard Worker class C: public B {
364*635a8641SAndroid Build Coastguard Worker public:
f()365*635a8641SAndroid Build Coastguard Worker void f() override { n_ += 2; }
366*635a8641SAndroid Build Coastguard Worker };
367*635a8641SAndroid Build Coastguard Worker
KillVptrAndCall(A * obj)368*635a8641SAndroid Build Coastguard Worker NOINLINE void KillVptrAndCall(A *obj) {
369*635a8641SAndroid Build Coastguard Worker *reinterpret_cast<void **>(obj) = 0;
370*635a8641SAndroid Build Coastguard Worker obj->f();
371*635a8641SAndroid Build Coastguard Worker }
372*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,BadVirtualCallNull)373*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, BadVirtualCallNull) {
374*635a8641SAndroid Build Coastguard Worker A a;
375*635a8641SAndroid Build Coastguard Worker B b;
376*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH({ KillVptrAndCall(&a); KillVptrAndCall(&b); }, CFI_ERROR_MSG);
377*635a8641SAndroid Build Coastguard Worker }
378*635a8641SAndroid Build Coastguard Worker
OverwriteVptrAndCall(B * obj,A * vptr)379*635a8641SAndroid Build Coastguard Worker NOINLINE void OverwriteVptrAndCall(B *obj, A *vptr) {
380*635a8641SAndroid Build Coastguard Worker *reinterpret_cast<void **>(obj) = *reinterpret_cast<void **>(vptr);
381*635a8641SAndroid Build Coastguard Worker obj->f();
382*635a8641SAndroid Build Coastguard Worker }
383*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,BadVirtualCallWrongType)384*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, BadVirtualCallWrongType) {
385*635a8641SAndroid Build Coastguard Worker A a;
386*635a8641SAndroid Build Coastguard Worker B b;
387*635a8641SAndroid Build Coastguard Worker C c;
388*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH({ OverwriteVptrAndCall(&b, &a); OverwriteVptrAndCall(&b, &c); },
389*635a8641SAndroid Build Coastguard Worker CFI_ERROR_MSG);
390*635a8641SAndroid Build Coastguard Worker }
391*635a8641SAndroid Build Coastguard Worker
392*635a8641SAndroid Build Coastguard Worker // TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794.
393*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(CFI_CAST_CHECK)
TEST(ToolsSanityTest,BadDerivedCast)394*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, BadDerivedCast) {
395*635a8641SAndroid Build Coastguard Worker A a;
396*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
397*635a8641SAndroid Build Coastguard Worker }
398*635a8641SAndroid Build Coastguard Worker
TEST(ToolsSanityTest,BadUnrelatedCast)399*635a8641SAndroid Build Coastguard Worker TEST(ToolsSanityTest, BadUnrelatedCast) {
400*635a8641SAndroid Build Coastguard Worker class A {
401*635a8641SAndroid Build Coastguard Worker virtual void f() {}
402*635a8641SAndroid Build Coastguard Worker };
403*635a8641SAndroid Build Coastguard Worker
404*635a8641SAndroid Build Coastguard Worker class B {
405*635a8641SAndroid Build Coastguard Worker virtual void f() {}
406*635a8641SAndroid Build Coastguard Worker };
407*635a8641SAndroid Build Coastguard Worker
408*635a8641SAndroid Build Coastguard Worker A a;
409*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
410*635a8641SAndroid Build Coastguard Worker }
411*635a8641SAndroid Build Coastguard Worker #endif // BUILDFLAG(CFI_CAST_CHECK)
412*635a8641SAndroid Build Coastguard Worker
413*635a8641SAndroid Build Coastguard Worker #endif // CFI_ERROR_MSG
414*635a8641SAndroid Build Coastguard Worker
415*635a8641SAndroid Build Coastguard Worker #undef CFI_ERROR_MSG
416*635a8641SAndroid Build Coastguard Worker #undef MAYBE_AccessesToNewMemory
417*635a8641SAndroid Build Coastguard Worker #undef MAYBE_AccessesToMallocMemory
418*635a8641SAndroid Build Coastguard Worker #undef MAYBE_ArrayDeletedWithoutBraces
419*635a8641SAndroid Build Coastguard Worker #undef MAYBE_SingleElementDeletedWithBraces
420*635a8641SAndroid Build Coastguard Worker #undef HARMFUL_ACCESS
421*635a8641SAndroid Build Coastguard Worker #undef HARMFUL_ACCESS_IS_NOOP
422*635a8641SAndroid Build Coastguard Worker
423*635a8641SAndroid Build Coastguard Worker } // namespace base
424