xref: /aosp_15_r20/external/webrtc/rtc_tools/sanitizers_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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