blob: 550845c2dc4e870c441f252e2ac6618c99d76323 [file] [log] [blame]
[email protected]44106182012-04-06 03:53:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]0716cba2009-12-17 12:37:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]c2a18492011-10-05 13:22:504//
5// This file contains intentional memory errors, some of which may lead to
6// crashes if the test is ran without special memory testing tools. We use these
7// errors to verify the sanity of the tools.
[email protected]0716cba2009-12-17 12:37:588
avi9b6f42932015-12-26 22:15:149#include <stddef.h>
10
[email protected]f49ecd8f2011-05-10 18:03:3411#include "base/atomicops.h"
[email protected]b4b34792014-06-14 08:29:3712#include "base/debug/asan_invalid_access.h"
13#include "base/debug/profiler.h"
[email protected]495cad92013-07-18 08:12:4014#include "base/message_loop/message_loop.h"
[email protected]ee857512010-05-14 08:24:4215#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
[email protected]34b99632011-01-01 01:01:0616#include "base/threading/thread.h"
avi9b6f42932015-12-26 22:15:1417#include "build/build_config.h"
[email protected]0716cba2009-12-17 12:37:5818#include "testing/gtest/include/gtest/gtest.h"
19
[email protected]ce072a72010-12-31 20:02:1620namespace base {
21
[email protected]0716cba2009-12-17 12:37:5822namespace {
23
[email protected]f49ecd8f2011-05-10 18:03:3424const base::subtle::Atomic32 kMagicValue = 42;
[email protected]0716cba2009-12-17 12:37:5825
[email protected]c2a18492011-10-05 13:22:5026// Helper for memory accesses that can potentially corrupt memory or cause a
27// crash during a native run.
[email protected]aee2f332014-03-27 15:08:0428#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
[email protected]9a4f6182012-10-24 14:11:0229#if defined(OS_IOS)
30// EXPECT_DEATH is not supported on IOS.
31#define HARMFUL_ACCESS(action,error_regexp) do { action; } while (0)
[email protected]b4b34792014-06-14 08:29:3732#elif defined(SYZYASAN)
33// We won't get a meaningful error message because we're not running under the
34// SyzyASan logger, but we can at least make sure that the error has been
35// generated in the SyzyASan runtime.
36#define HARMFUL_ACCESS(action,unused) \
37if (debug::IsBinaryInstrumented()) { EXPECT_DEATH(action, \
38 "AsanRuntime::OnError"); }
[email protected]9a4f6182012-10-24 14:11:0239#else
[email protected]c2a18492011-10-05 13:22:5040#define HARMFUL_ACCESS(action,error_regexp) EXPECT_DEATH(action,error_regexp)
[email protected]b4b34792014-06-14 08:29:3741#endif // !OS_IOS && !SYZYASAN
[email protected]c2a18492011-10-05 13:22:5042#else
43#define HARMFUL_ACCESS(action,error_regexp) \
44do { if (RunningOnValgrind()) { action; } } while (0)
45#endif
46
[email protected]1e51a962014-01-16 05:31:4147void DoReadUninitializedValue(char *ptr) {
[email protected]43dea192012-05-16 08:42:0848 // Comparison with 64 is to prevent clang from optimizing away the
[email protected]83a13b22011-09-18 16:39:1249 // jump -- valgrind only catches jumps and conditional moves, but clang uses
50 // the borrow flag if the condition is just `*ptr == '\0'`.
[email protected]43dea192012-05-16 08:42:0851 if (*ptr == 64) {
[email protected]1e51a962014-01-16 05:31:4152 VLOG(1) << "Uninit condition is true";
[email protected]adf7d802010-09-23 09:12:3753 } else {
[email protected]1e51a962014-01-16 05:31:4154 VLOG(1) << "Uninit condition is false";
[email protected]adf7d802010-09-23 09:12:3755 }
56}
57
[email protected]1e51a962014-01-16 05:31:4158void ReadUninitializedValue(char *ptr) {
59#if defined(MEMORY_SANITIZER)
60 EXPECT_DEATH(DoReadUninitializedValue(ptr),
61 "use-of-uninitialized-value");
62#else
63 DoReadUninitializedValue(ptr);
64#endif
65}
66
[email protected]9ded9912010-03-26 12:54:4467void ReadValueOutOfArrayBoundsLeft(char *ptr) {
[email protected]45b9eba2010-10-18 23:57:4968 char c = ptr[-2];
69 VLOG(1) << "Reading a byte out of bounds: " << c;
[email protected]9ded9912010-03-26 12:54:4470}
71
72void ReadValueOutOfArrayBoundsRight(char *ptr, size_t size) {
[email protected]45b9eba2010-10-18 23:57:4973 char c = ptr[size + 1];
74 VLOG(1) << "Reading a byte out of bounds: " << c;
[email protected]9ded9912010-03-26 12:54:4475}
76
77// This is harmless if you run it under Valgrind thanks to redzones.
78void WriteValueOutOfArrayBoundsLeft(char *ptr) {
[email protected]f49ecd8f2011-05-10 18:03:3479 ptr[-1] = kMagicValue;
[email protected]9ded9912010-03-26 12:54:4480}
81
82// This is harmless if you run it under Valgrind thanks to redzones.
83void WriteValueOutOfArrayBoundsRight(char *ptr, size_t size) {
[email protected]f49ecd8f2011-05-10 18:03:3484 ptr[size] = kMagicValue;
[email protected]9ded9912010-03-26 12:54:4485}
86
87void MakeSomeErrors(char *ptr, size_t size) {
[email protected]adf7d802010-09-23 09:12:3788 ReadUninitializedValue(ptr);
[email protected]e260ebc2013-12-18 05:31:3389
[email protected]c2a18492011-10-05 13:22:5090 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsLeft(ptr),
[email protected]e260ebc2013-12-18 05:31:3391 "2 bytes to the left");
[email protected]c2a18492011-10-05 13:22:5092 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsRight(ptr, size),
[email protected]e260ebc2013-12-18 05:31:3393 "1 bytes to the right");
[email protected]c2a18492011-10-05 13:22:5094 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsLeft(ptr),
[email protected]e260ebc2013-12-18 05:31:3395 "1 bytes to the left");
[email protected]c2a18492011-10-05 13:22:5096 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsRight(ptr, size),
[email protected]e260ebc2013-12-18 05:31:3397 "0 bytes to the right");
[email protected]9ded9912010-03-26 12:54:4498}
99
[email protected]66d051bb2010-10-14 08:25:54100} // namespace
101
102// A memory leak detector should report an error in this test.
103TEST(ToolsSanityTest, MemoryLeak) {
[email protected]6bfad0e2011-11-01 11:08:09104 // Without the |volatile|, clang optimizes away the next two lines.
105 int* volatile leak = new int[256]; // Leak some memory intentionally.
[email protected]66d051bb2010-10-14 08:25:54106 leak[4] = 1; // Make sure the allocated memory is used.
107}
108
[email protected]3da8c162014-03-28 17:35:10109#if (defined(ADDRESS_SANITIZER) && defined(OS_IOS)) || defined(SYZYASAN)
[email protected]9a4f6182012-10-24 14:11:02110// Because iOS doesn't support death tests, each of the following tests will
[email protected]3da8c162014-03-28 17:35:10111// crash the whole program under Asan. On Windows Asan is based on SyzyAsan; the
112// error report mechanism is different than with Asan so these tests will fail.
[email protected]9a4f6182012-10-24 14:11:02113#define MAYBE_AccessesToNewMemory DISABLED_AccessesToNewMemory
114#define MAYBE_AccessesToMallocMemory DISABLED_AccessesToMallocMemory
[email protected]2d4e0132014-05-14 11:50:37115#else
116#define MAYBE_AccessesToNewMemory AccessesToNewMemory
117#define MAYBE_AccessesToMallocMemory AccessesToMallocMemory
[email protected]de0c7ed52014-07-18 02:40:40118#endif // (defined(ADDRESS_SANITIZER) && defined(OS_IOS)) || defined(SYZYASAN)
[email protected]f5162802014-05-14 16:04:30119
120// The following tests pass with Clang r170392, but not r172454, which
121// makes AddressSanitizer detect errors in them. We disable these tests under
122// AddressSanitizer until we fully switch to Clang r172454. After that the
123// tests should be put back under the (defined(OS_IOS) || defined(OS_WIN))
124// clause above.
125// See also http://crbug.com/172614.
126#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
[email protected]2d4e0132014-05-14 11:50:37127#define MAYBE_SingleElementDeletedWithBraces \
128 DISABLED_SingleElementDeletedWithBraces
[email protected]f5162802014-05-14 16:04:30129#define MAYBE_ArrayDeletedWithoutBraces DISABLED_ArrayDeletedWithoutBraces
[email protected]de0c7ed52014-07-18 02:40:40130#else
131#define MAYBE_ArrayDeletedWithoutBraces ArrayDeletedWithoutBraces
132#define MAYBE_SingleElementDeletedWithBraces SingleElementDeletedWithBraces
133#endif // defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
134
[email protected]9a4f6182012-10-24 14:11:02135TEST(ToolsSanityTest, MAYBE_AccessesToNewMemory) {
[email protected]9ded9912010-03-26 12:54:44136 char *foo = new char[10];
137 MakeSomeErrors(foo, 10);
138 delete [] foo;
[email protected]c2a18492011-10-05 13:22:50139 // Use after delete.
140 HARMFUL_ACCESS(foo[5] = 0, "heap-use-after-free");
[email protected]9ded9912010-03-26 12:54:44141}
142
[email protected]9a4f6182012-10-24 14:11:02143TEST(ToolsSanityTest, MAYBE_AccessesToMallocMemory) {
[email protected]9ded9912010-03-26 12:54:44144 char *foo = reinterpret_cast<char*>(malloc(10));
145 MakeSomeErrors(foo, 10);
146 free(foo);
[email protected]c2a18492011-10-05 13:22:50147 // Use after free.
148 HARMFUL_ACCESS(foo[5] = 0, "heap-use-after-free");
[email protected]9ded9912010-03-26 12:54:44149}
150
hanscd4cce32015-05-19 17:03:14151static int* allocateArray() {
152 // Clang warns about the mismatched new[]/delete if they occur in the same
153 // function.
154 return new int[10];
155}
156
[email protected]9a4f6182012-10-24 14:11:02157TEST(ToolsSanityTest, MAYBE_ArrayDeletedWithoutBraces) {
[email protected]aee2f332014-03-27 15:08:04158#if !defined(ADDRESS_SANITIZER) && !defined(SYZYASAN)
[email protected]c2a18492011-10-05 13:22:50159 // This test may corrupt memory if not run under Valgrind or compiled with
160 // AddressSanitizer.
[email protected]9ded9912010-03-26 12:54:44161 if (!RunningOnValgrind())
162 return;
[email protected]c2a18492011-10-05 13:22:50163#endif
[email protected]9ded9912010-03-26 12:54:44164
[email protected]014b0b062011-09-18 16:30:12165 // Without the |volatile|, clang optimizes away the next two lines.
hanscd4cce32015-05-19 17:03:14166 int* volatile foo = allocateArray();
[email protected]f5162802014-05-14 16:04:30167 delete foo;
[email protected]9ded9912010-03-26 12:54:44168}
169
hanscd4cce32015-05-19 17:03:14170static int* allocateScalar() {
171 // Clang warns about the mismatched new/delete[] if they occur in the same
172 // function.
173 return new int;
174}
175
[email protected]9a4f6182012-10-24 14:11:02176TEST(ToolsSanityTest, MAYBE_SingleElementDeletedWithBraces) {
177#if !defined(ADDRESS_SANITIZER)
[email protected]c2a18492011-10-05 13:22:50178 // This test may corrupt memory if not run under Valgrind or compiled with
179 // AddressSanitizer.
[email protected]9ded9912010-03-26 12:54:44180 if (!RunningOnValgrind())
181 return;
[email protected]c2a18492011-10-05 13:22:50182#endif
[email protected]9ded9912010-03-26 12:54:44183
[email protected]014b0b062011-09-18 16:30:12184 // Without the |volatile|, clang optimizes away the next two lines.
hanscd4cce32015-05-19 17:03:14185 int* volatile foo = allocateScalar();
[email protected]928ca1d2011-09-30 18:52:04186 (void) foo;
[email protected]f5162802014-05-14 16:04:30187 delete [] foo;
[email protected]9ded9912010-03-26 12:54:44188}
189
[email protected]aee2f332014-03-27 15:08:04190#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
[email protected]b4b34792014-06-14 08:29:37191
[email protected]9b147ae2011-11-08 09:28:49192TEST(ToolsSanityTest, DISABLED_AddressSanitizerNullDerefCrashTest) {
[email protected]6fcbc62f2011-10-12 17:18:24193 // Intentionally crash to make sure AddressSanitizer is running.
194 // This test should not be ran on bots.
195 int* volatile zero = NULL;
196 *zero = 0;
197}
[email protected]9b147ae2011-11-08 09:28:49198
199TEST(ToolsSanityTest, DISABLED_AddressSanitizerLocalOOBCrashTest) {
200 // Intentionally crash to make sure AddressSanitizer is instrumenting
201 // the local variables.
202 // This test should not be ran on bots.
203 int array[5];
204 // Work around the OOB warning reported by Clang.
205 int* volatile access = &array[5];
206 *access = 43;
207}
208
209namespace {
210int g_asan_test_global_array[10];
211} // namespace
212
213TEST(ToolsSanityTest, DISABLED_AddressSanitizerGlobalOOBCrashTest) {
214 // Intentionally crash to make sure AddressSanitizer is instrumenting
215 // the global variables.
216 // This test should not be ran on bots.
217
218 // Work around the OOB warning reported by Clang.
219 int* volatile access = g_asan_test_global_array - 1;
220 *access = 43;
221}
222
[email protected]b4b34792014-06-14 08:29:37223TEST(ToolsSanityTest, AsanHeapOverflow) {
224 HARMFUL_ACCESS(debug::AsanHeapOverflow() ,"to the right");
225}
226
227TEST(ToolsSanityTest, AsanHeapUnderflow) {
228 HARMFUL_ACCESS(debug::AsanHeapUnderflow(), "to the left");
229}
230
231TEST(ToolsSanityTest, AsanHeapUseAfterFree) {
232 HARMFUL_ACCESS(debug::AsanHeapUseAfterFree(), "heap-use-after-free");
233}
234
235#if defined(SYZYASAN)
236TEST(ToolsSanityTest, AsanCorruptHeapBlock) {
237 HARMFUL_ACCESS(debug::AsanCorruptHeapBlock(), "");
238}
239
240TEST(ToolsSanityTest, AsanCorruptHeap) {
241 // This test will kill the process by raising an exception, there's no
242 // particular string to look for in the stack trace.
243 EXPECT_DEATH(debug::AsanCorruptHeap(), "");
244}
245#endif // SYZYASAN
246
247#endif // ADDRESS_SANITIZER || SYZYASAN
[email protected]f49ecd8f2011-05-10 18:03:34248
249namespace {
250
251// We use caps here just to ensure that the method name doesn't interfere with
252// the wildcarded suppressions.
253class TOOLS_SANITY_TEST_CONCURRENT_THREAD : public PlatformThread::Delegate {
254 public:
255 explicit TOOLS_SANITY_TEST_CONCURRENT_THREAD(bool *value) : value_(value) {}
dcheng56488182014-10-21 10:54:51256 ~TOOLS_SANITY_TEST_CONCURRENT_THREAD() override {}
257 void ThreadMain() override {
[email protected]f49ecd8f2011-05-10 18:03:34258 *value_ = true;
259
260 // Sleep for a few milliseconds so the two threads are more likely to live
261 // simultaneously. Otherwise we may miss the report due to mutex
262 // lock/unlock's inside thread creation code in pure-happens-before mode...
[email protected]a1b75b942011-12-31 22:53:51263 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
[email protected]f49ecd8f2011-05-10 18:03:34264 }
265 private:
266 bool *value_;
267};
268
269class ReleaseStoreThread : public PlatformThread::Delegate {
270 public:
271 explicit ReleaseStoreThread(base::subtle::Atomic32 *value) : value_(value) {}
dcheng56488182014-10-21 10:54:51272 ~ReleaseStoreThread() override {}
273 void ThreadMain() override {
[email protected]f49ecd8f2011-05-10 18:03:34274 base::subtle::Release_Store(value_, kMagicValue);
275
276 // Sleep for a few milliseconds so the two threads are more likely to live
277 // simultaneously. Otherwise we may miss the report due to mutex
278 // lock/unlock's inside thread creation code in pure-happens-before mode...
[email protected]a1b75b942011-12-31 22:53:51279 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
[email protected]f49ecd8f2011-05-10 18:03:34280 }
281 private:
282 base::subtle::Atomic32 *value_;
283};
284
285class AcquireLoadThread : public PlatformThread::Delegate {
286 public:
287 explicit AcquireLoadThread(base::subtle::Atomic32 *value) : value_(value) {}
dcheng56488182014-10-21 10:54:51288 ~AcquireLoadThread() override {}
289 void ThreadMain() override {
[email protected]f49ecd8f2011-05-10 18:03:34290 // Wait for the other thread to make Release_Store
[email protected]a1b75b942011-12-31 22:53:51291 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
[email protected]f49ecd8f2011-05-10 18:03:34292 base::subtle::Acquire_Load(value_);
293 }
294 private:
295 base::subtle::Atomic32 *value_;
296};
297
298void RunInParallel(PlatformThread::Delegate *d1, PlatformThread::Delegate *d2) {
299 PlatformThreadHandle a;
300 PlatformThreadHandle b;
301 PlatformThread::Create(0, d1, &a);
302 PlatformThread::Create(0, d2, &b);
303 PlatformThread::Join(a);
304 PlatformThread::Join(b);
305}
306
[email protected]b11d38d02014-06-26 13:10:50307#if defined(THREAD_SANITIZER)
308void DataRace() {
[email protected]a4057982013-03-23 11:28:17309 bool *shared = new bool(false);
310 TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(shared), thread2(shared);
[email protected]f49ecd8f2011-05-10 18:03:34311 RunInParallel(&thread1, &thread2);
[email protected]a4057982013-03-23 11:28:17312 EXPECT_TRUE(*shared);
313 delete shared;
[email protected]b11d38d02014-06-26 13:10:50314 // We're in a death test - crash.
315 CHECK(0);
[email protected]f49ecd8f2011-05-10 18:03:34316}
[email protected]b11d38d02014-06-26 13:10:50317#endif
318
319} // namespace
320
321#if defined(THREAD_SANITIZER)
322// A data race detector should report an error in this test.
323TEST(ToolsSanityTest, DataRace) {
324 // The suppression regexp must match that in base/debug/tsan_suppressions.cc.
325 EXPECT_DEATH(DataRace(), "1 race:base/tools_sanity_unittest.cc");
326}
327#endif
[email protected]f49ecd8f2011-05-10 18:03:34328
329TEST(ToolsSanityTest, AnnotateBenignRace) {
330 bool shared = false;
331 ANNOTATE_BENIGN_RACE(&shared, "Intentional race - make sure doesn't show up");
332 TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(&shared), thread2(&shared);
333 RunInParallel(&thread1, &thread2);
334 EXPECT_TRUE(shared);
335}
336
337TEST(ToolsSanityTest, AtomicsAreIgnored) {
338 base::subtle::Atomic32 shared = 0;
339 ReleaseStoreThread thread1(&shared);
340 AcquireLoadThread thread2(&shared);
341 RunInParallel(&thread1, &thread2);
342 EXPECT_EQ(kMagicValue, shared);
[email protected]0716cba2009-12-17 12:37:58343}
[email protected]ce072a72010-12-31 20:02:16344
Vlad Tsyrklevich37f1e352017-08-15 23:45:10345#if defined(CFI_ENFORCEMENT_TRAP)
Peter Collingbourne355546f2017-10-12 19:51:27346#if defined(OS_WIN)
347#define CFI_ERROR_MSG "EXCEPTION_ILLEGAL_INSTRUCTION"
348#elif defined(OS_ANDROID)
349// TODO(pcc): Produce proper stack dumps on Android and test for the correct
350// si_code here.
351#define CFI_ERROR_MSG "^$"
352#else
Vlad Tsyrklevich37f1e352017-08-15 23:45:10353#define CFI_ERROR_MSG "ILL_ILLOPN"
Peter Collingbourne355546f2017-10-12 19:51:27354#endif
Vlad Tsyrklevich37f1e352017-08-15 23:45:10355#elif defined(CFI_ENFORCEMENT_DIAGNOSTIC)
356#define CFI_ERROR_MSG "runtime error: control flow integrity check"
357#endif // CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC
pcc07364912015-07-31 00:19:06358
Vlad Tsyrklevich37f1e352017-08-15 23:45:10359#if defined(CFI_ERROR_MSG)
krasin59d37182016-07-13 03:24:34360class A {
361 public:
362 A(): n_(0) {}
363 virtual void f() { n_++; }
364 protected:
365 int n_;
366};
367
368class B: public A {
369 public:
370 void f() override { n_--; }
371};
372
Vlad Tsyrklevich37f1e352017-08-15 23:45:10373class C: public B {
374 public:
375 void f() override { n_ += 2; }
376};
377
krasin59d37182016-07-13 03:24:34378NOINLINE void KillVptrAndCall(A *obj) {
379 *reinterpret_cast<void **>(obj) = 0;
380 obj->f();
381}
382
Vlad Tsyrklevich37f1e352017-08-15 23:45:10383TEST(ToolsSanityTest, BadVirtualCallNull) {
krasin59d37182016-07-13 03:24:34384 A a;
385 B b;
Vlad Tsyrklevich37f1e352017-08-15 23:45:10386 EXPECT_DEATH({ KillVptrAndCall(&a); KillVptrAndCall(&b); }, CFI_ERROR_MSG);
krasin59d37182016-07-13 03:24:34387}
388
Vlad Tsyrklevich37f1e352017-08-15 23:45:10389NOINLINE void OverwriteVptrAndCall(B *obj, A *vptr) {
390 *reinterpret_cast<void **>(obj) = *reinterpret_cast<void **>(vptr);
391 obj->f();
392}
393
394TEST(ToolsSanityTest, BadVirtualCallWrongType) {
395 A a;
396 B b;
397 C c;
398 EXPECT_DEATH({ OverwriteVptrAndCall(&b, &a); OverwriteVptrAndCall(&b, &c); },
399 CFI_ERROR_MSG);
400}
401
402// TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794.
403#if defined(CFI_CAST_CHECK)
404TEST(ToolsSanityTest, BadDerivedCast) {
405 A a;
406 EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
407}
408
409TEST(ToolsSanityTest, BadUnrelatedCast) {
410 class A {
411 virtual void f() {}
412 };
413
414 class B {
415 virtual void f() {}
416 };
417
418 A a;
419 EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
420}
421#endif // CFI_CAST_CHECK
422
423#endif // CFI_ERROR_MSG
pcc07364912015-07-31 00:19:06424
[email protected]ce072a72010-12-31 20:02:16425} // namespace base