1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
12*d9f75844SAndroid Build Coastguard Worker #include <stdio.h>
13*d9f75844SAndroid Build Coastguard Worker
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <random>
16*d9f75844SAndroid Build Coastguard Worker
17*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/null_socket_server.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
20*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
21*d9f75844SAndroid Build Coastguard Worker
22*d9f75844SAndroid Build Coastguard Worker namespace rtc {
23*d9f75844SAndroid Build Coastguard Worker
24*d9f75844SAndroid Build Coastguard Worker namespace {
25*d9f75844SAndroid Build Coastguard Worker
26*d9f75844SAndroid Build Coastguard Worker #if defined(MEMORY_SANITIZER)
UseOfUninitializedValue()27*d9f75844SAndroid Build Coastguard Worker void UseOfUninitializedValue() {
28*d9f75844SAndroid Build Coastguard Worker int* buf = new int[2];
29*d9f75844SAndroid Build Coastguard Worker std::random_device engine;
30*d9f75844SAndroid Build Coastguard Worker if (buf[engine() % 2]) { // Non-deterministic conditional.
31*d9f75844SAndroid Build Coastguard Worker printf("Externally visible action.");
32*d9f75844SAndroid Build Coastguard Worker }
33*d9f75844SAndroid Build Coastguard Worker delete[] buf;
34*d9f75844SAndroid Build Coastguard Worker }
35*d9f75844SAndroid Build Coastguard Worker
TEST(SanitizersDeathTest,MemorySanitizer)36*d9f75844SAndroid Build Coastguard Worker TEST(SanitizersDeathTest, MemorySanitizer) {
37*d9f75844SAndroid Build Coastguard Worker EXPECT_DEATH(UseOfUninitializedValue(), "use-of-uninitialized-value");
38*d9f75844SAndroid Build Coastguard Worker }
39*d9f75844SAndroid Build Coastguard Worker #endif
40*d9f75844SAndroid Build Coastguard Worker
41*d9f75844SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
HeapUseAfterFree()42*d9f75844SAndroid Build Coastguard Worker void HeapUseAfterFree() {
43*d9f75844SAndroid Build Coastguard Worker char* buf = new char[2];
44*d9f75844SAndroid Build Coastguard Worker delete[] buf;
45*d9f75844SAndroid Build Coastguard Worker buf[0] = buf[1];
46*d9f75844SAndroid Build Coastguard Worker }
47*d9f75844SAndroid Build Coastguard Worker
TEST(SanitizersDeathTest,AddressSanitizer)48*d9f75844SAndroid Build Coastguard Worker TEST(SanitizersDeathTest, AddressSanitizer) {
49*d9f75844SAndroid Build Coastguard Worker EXPECT_DEATH(HeapUseAfterFree(), "heap-use-after-free");
50*d9f75844SAndroid Build Coastguard Worker }
51*d9f75844SAndroid Build Coastguard Worker #endif
52*d9f75844SAndroid Build Coastguard Worker
53*d9f75844SAndroid Build Coastguard Worker #if defined(UNDEFINED_SANITIZER)
54*d9f75844SAndroid Build Coastguard Worker // For ubsan:
SignedIntegerOverflow()55*d9f75844SAndroid Build Coastguard Worker void SignedIntegerOverflow() {
56*d9f75844SAndroid Build Coastguard Worker int32_t x = 1234567890;
57*d9f75844SAndroid Build Coastguard Worker x *= 2;
58*d9f75844SAndroid Build Coastguard Worker (void)x;
59*d9f75844SAndroid Build Coastguard Worker }
60*d9f75844SAndroid Build Coastguard Worker
61*d9f75844SAndroid Build Coastguard Worker // For ubsan_vptr:
62*d9f75844SAndroid Build Coastguard Worker struct Base {
frtc::__anon606cdf240111::Base63*d9f75844SAndroid Build Coastguard Worker virtual void f() {}
~Basertc::__anon606cdf240111::Base64*d9f75844SAndroid Build Coastguard Worker virtual ~Base() {}
65*d9f75844SAndroid Build Coastguard Worker };
66*d9f75844SAndroid Build Coastguard Worker struct Derived : public Base {};
67*d9f75844SAndroid Build Coastguard Worker
InvalidVptr()68*d9f75844SAndroid Build Coastguard Worker void InvalidVptr() {
69*d9f75844SAndroid Build Coastguard Worker Base b;
70*d9f75844SAndroid Build Coastguard Worker auto* d = static_cast<Derived*>(&b); // Bad downcast.
71*d9f75844SAndroid Build Coastguard Worker d->f(); // Virtual function call with object of wrong dynamic type.
72*d9f75844SAndroid Build Coastguard Worker }
73*d9f75844SAndroid Build Coastguard Worker
TEST(SanitizersDeathTest,UndefinedSanitizer)74*d9f75844SAndroid Build Coastguard Worker TEST(SanitizersDeathTest, UndefinedSanitizer) {
75*d9f75844SAndroid Build Coastguard Worker EXPECT_DEATH(
76*d9f75844SAndroid Build Coastguard Worker {
77*d9f75844SAndroid Build Coastguard Worker SignedIntegerOverflow();
78*d9f75844SAndroid Build Coastguard Worker InvalidVptr();
79*d9f75844SAndroid Build Coastguard Worker },
80*d9f75844SAndroid Build Coastguard Worker "runtime error");
81*d9f75844SAndroid Build Coastguard Worker }
82*d9f75844SAndroid Build Coastguard Worker #endif
83*d9f75844SAndroid Build Coastguard Worker
84*d9f75844SAndroid Build Coastguard Worker #if defined(THREAD_SANITIZER)
85*d9f75844SAndroid Build Coastguard Worker class IncrementThread : public Thread {
86*d9f75844SAndroid Build Coastguard Worker public:
IncrementThread(int * value)87*d9f75844SAndroid Build Coastguard Worker explicit IncrementThread(int* value)
88*d9f75844SAndroid Build Coastguard Worker : Thread(std::make_unique<NullSocketServer>()), value_(value) {}
89*d9f75844SAndroid Build Coastguard Worker
90*d9f75844SAndroid Build Coastguard Worker IncrementThread(const IncrementThread&) = delete;
91*d9f75844SAndroid Build Coastguard Worker IncrementThread& operator=(const IncrementThread&) = delete;
92*d9f75844SAndroid Build Coastguard Worker
Run()93*d9f75844SAndroid Build Coastguard Worker void Run() override {
94*d9f75844SAndroid Build Coastguard Worker ++*value_;
95*d9f75844SAndroid Build Coastguard Worker Thread::Current()->SleepMs(100);
96*d9f75844SAndroid Build Coastguard Worker }
97*d9f75844SAndroid Build Coastguard Worker
98*d9f75844SAndroid Build Coastguard Worker // Un-protect Thread::Join for the test.
Join()99*d9f75844SAndroid Build Coastguard Worker void Join() { Thread::Join(); }
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard Worker private:
102*d9f75844SAndroid Build Coastguard Worker int* value_;
103*d9f75844SAndroid Build Coastguard Worker };
104*d9f75844SAndroid Build Coastguard Worker
DataRace()105*d9f75844SAndroid Build Coastguard Worker void DataRace() {
106*d9f75844SAndroid Build Coastguard Worker int value = 0;
107*d9f75844SAndroid Build Coastguard Worker IncrementThread thread1(&value);
108*d9f75844SAndroid Build Coastguard Worker IncrementThread thread2(&value);
109*d9f75844SAndroid Build Coastguard Worker thread1.Start();
110*d9f75844SAndroid Build Coastguard Worker thread2.Start();
111*d9f75844SAndroid Build Coastguard Worker thread1.Join();
112*d9f75844SAndroid Build Coastguard Worker thread2.Join();
113*d9f75844SAndroid Build Coastguard Worker // TSan seems to mess with gtest's death detection.
114*d9f75844SAndroid Build Coastguard Worker // Fail intentionally, and rely on detecting the error message.
115*d9f75844SAndroid Build Coastguard Worker RTC_CHECK_NOTREACHED();
116*d9f75844SAndroid Build Coastguard Worker }
117*d9f75844SAndroid Build Coastguard Worker
TEST(SanitizersDeathTest,ThreadSanitizer)118*d9f75844SAndroid Build Coastguard Worker TEST(SanitizersDeathTest, ThreadSanitizer) {
119*d9f75844SAndroid Build Coastguard Worker EXPECT_DEATH(DataRace(), "data race");
120*d9f75844SAndroid Build Coastguard Worker }
121*d9f75844SAndroid Build Coastguard Worker #endif
122*d9f75844SAndroid Build Coastguard Worker
123*d9f75844SAndroid Build Coastguard Worker } // namespace
124*d9f75844SAndroid Build Coastguard Worker
125*d9f75844SAndroid Build Coastguard Worker } // namespace rtc
126