1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker // Smoke tests to verify that clang sanitizers are actually working.
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard Worker #include <pthread.h>
20*6dbdd20aSAndroid Build Coastguard Worker #include <stdint.h>
21*6dbdd20aSAndroid Build Coastguard Worker
22*6dbdd20aSAndroid Build Coastguard Worker #include <memory>
23*6dbdd20aSAndroid Build Coastguard Worker
24*6dbdd20aSAndroid Build Coastguard Worker #include "test/gtest_and_gmock.h"
25*6dbdd20aSAndroid Build Coastguard Worker
26*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
27*6dbdd20aSAndroid Build Coastguard Worker namespace {
28*6dbdd20aSAndroid Build Coastguard Worker
29*6dbdd20aSAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
TEST(SanitizerTests,ASAN_UserAfterFree)30*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, ASAN_UserAfterFree) {
31*6dbdd20aSAndroid Build Coastguard Worker EXPECT_DEATH(
32*6dbdd20aSAndroid Build Coastguard Worker {
33*6dbdd20aSAndroid Build Coastguard Worker void* alloc = malloc(16);
34*6dbdd20aSAndroid Build Coastguard Worker volatile char* mem = reinterpret_cast<volatile char*>(alloc);
35*6dbdd20aSAndroid Build Coastguard Worker mem[0] = 1;
36*6dbdd20aSAndroid Build Coastguard Worker mem[15] = 1;
37*6dbdd20aSAndroid Build Coastguard Worker free(alloc);
38*6dbdd20aSAndroid Build Coastguard Worker mem[0] = 2;
39*6dbdd20aSAndroid Build Coastguard Worker abort();
40*6dbdd20aSAndroid Build Coastguard Worker },
41*6dbdd20aSAndroid Build Coastguard Worker "AddressSanitizer:.*heap-use-after-free");
42*6dbdd20aSAndroid Build Coastguard Worker }
43*6dbdd20aSAndroid Build Coastguard Worker #endif // ADDRESS_SANITIZER
44*6dbdd20aSAndroid Build Coastguard Worker
45*6dbdd20aSAndroid Build Coastguard Worker #if defined(MEMORY_SANITIZER)
TEST(SanitizerTests,MSAN_UninitializedMemory)46*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, MSAN_UninitializedMemory) {
47*6dbdd20aSAndroid Build Coastguard Worker EXPECT_DEATH(
48*6dbdd20aSAndroid Build Coastguard Worker {
49*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<int> mem(new int[10]);
50*6dbdd20aSAndroid Build Coastguard Worker volatile int* x = reinterpret_cast<volatile int*>(mem.get());
51*6dbdd20aSAndroid Build Coastguard Worker if (x[rand() % 10] == 42)
52*6dbdd20aSAndroid Build Coastguard Worker printf("\n");
53*6dbdd20aSAndroid Build Coastguard Worker abort();
54*6dbdd20aSAndroid Build Coastguard Worker },
55*6dbdd20aSAndroid Build Coastguard Worker "MemorySanitizer:.*use-of-uninitialized-value");
56*6dbdd20aSAndroid Build Coastguard Worker }
57*6dbdd20aSAndroid Build Coastguard Worker #endif
58*6dbdd20aSAndroid Build Coastguard Worker
59*6dbdd20aSAndroid Build Coastguard Worker // b/141460117: Leak sanitizer tests don't work in debug builds.
60*6dbdd20aSAndroid Build Coastguard Worker #if defined(LEAK_SANITIZER) && defined(NDEBUG)
TEST(SanitizerTests,LSAN_LeakMalloc)61*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, LSAN_LeakMalloc) {
62*6dbdd20aSAndroid Build Coastguard Worker EXPECT_DEATH(
63*6dbdd20aSAndroid Build Coastguard Worker {
64*6dbdd20aSAndroid Build Coastguard Worker void* alloc = malloc(16);
65*6dbdd20aSAndroid Build Coastguard Worker reinterpret_cast<volatile char*>(alloc)[0] = 1;
66*6dbdd20aSAndroid Build Coastguard Worker alloc = malloc(16);
67*6dbdd20aSAndroid Build Coastguard Worker reinterpret_cast<volatile char*>(alloc)[0] = 2;
68*6dbdd20aSAndroid Build Coastguard Worker free(alloc);
69*6dbdd20aSAndroid Build Coastguard Worker exit(0); // LSan runs on the atexit handler.
70*6dbdd20aSAndroid Build Coastguard Worker },
71*6dbdd20aSAndroid Build Coastguard Worker "LeakSanitizer:.*detected memory leaks");
72*6dbdd20aSAndroid Build Coastguard Worker }
73*6dbdd20aSAndroid Build Coastguard Worker
TEST(SanitizerTests,LSAN_LeakCppNew)74*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, LSAN_LeakCppNew) {
75*6dbdd20aSAndroid Build Coastguard Worker EXPECT_DEATH(
76*6dbdd20aSAndroid Build Coastguard Worker {
77*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<int> alloc(new int(1));
78*6dbdd20aSAndroid Build Coastguard Worker *reinterpret_cast<volatile int*>(alloc.get()) = 1;
79*6dbdd20aSAndroid Build Coastguard Worker alloc.release();
80*6dbdd20aSAndroid Build Coastguard Worker alloc.reset(new int(2));
81*6dbdd20aSAndroid Build Coastguard Worker *reinterpret_cast<volatile int*>(alloc.get()) = 2;
82*6dbdd20aSAndroid Build Coastguard Worker exit(0); // LSan runs on the atexit handler.
83*6dbdd20aSAndroid Build Coastguard Worker },
84*6dbdd20aSAndroid Build Coastguard Worker "LeakSanitizer:.*detected memory leaks");
85*6dbdd20aSAndroid Build Coastguard Worker }
86*6dbdd20aSAndroid Build Coastguard Worker #endif // LEAK_SANITIZER && defined(NDEBUG)
87*6dbdd20aSAndroid Build Coastguard Worker
88*6dbdd20aSAndroid Build Coastguard Worker #if defined(UNDEFINED_SANITIZER)
TEST(SanitizerTests,UBSAN_DivisionByZero)89*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, UBSAN_DivisionByZero) {
90*6dbdd20aSAndroid Build Coastguard Worker EXPECT_DEATH(
91*6dbdd20aSAndroid Build Coastguard Worker {
92*6dbdd20aSAndroid Build Coastguard Worker volatile float div = 1;
93*6dbdd20aSAndroid Build Coastguard Worker float res = 3 / (div - 1);
94*6dbdd20aSAndroid Build Coastguard Worker ASSERT_GT(res, -1.0f); // just use |res| to make the compiler happy.
95*6dbdd20aSAndroid Build Coastguard Worker abort();
96*6dbdd20aSAndroid Build Coastguard Worker },
97*6dbdd20aSAndroid Build Coastguard Worker "error:.*division by zero");
98*6dbdd20aSAndroid Build Coastguard Worker }
99*6dbdd20aSAndroid Build Coastguard Worker
TEST(SanitizerTests,UBSAN_ShiftExponent)100*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, UBSAN_ShiftExponent) {
101*6dbdd20aSAndroid Build Coastguard Worker EXPECT_DEATH(
102*6dbdd20aSAndroid Build Coastguard Worker {
103*6dbdd20aSAndroid Build Coastguard Worker volatile uint32_t n = 32;
104*6dbdd20aSAndroid Build Coastguard Worker volatile uint32_t shift = 31;
105*6dbdd20aSAndroid Build Coastguard Worker uint64_t res = n << (shift + 3);
106*6dbdd20aSAndroid Build Coastguard Worker ASSERT_NE(1u, res); // just use |res| to make the compiler happy.
107*6dbdd20aSAndroid Build Coastguard Worker abort();
108*6dbdd20aSAndroid Build Coastguard Worker },
109*6dbdd20aSAndroid Build Coastguard Worker "error:.*shift exponent");
110*6dbdd20aSAndroid Build Coastguard Worker }
111*6dbdd20aSAndroid Build Coastguard Worker #endif // UNDEFINED_SANITIZER
112*6dbdd20aSAndroid Build Coastguard Worker
113*6dbdd20aSAndroid Build Coastguard Worker #if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
114*6dbdd20aSAndroid Build Coastguard Worker !defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER) && \
115*6dbdd20aSAndroid Build Coastguard Worker !defined(UNDEFINED_SANITIZER)
TEST(SanitizerTests,NoSanitizersConfigured)116*6dbdd20aSAndroid Build Coastguard Worker TEST(SanitizerTests, NoSanitizersConfigured) {
117*6dbdd20aSAndroid Build Coastguard Worker printf("No sanitizers configured!\n");
118*6dbdd20aSAndroid Build Coastguard Worker }
119*6dbdd20aSAndroid Build Coastguard Worker #endif
120*6dbdd20aSAndroid Build Coastguard Worker
121*6dbdd20aSAndroid Build Coastguard Worker } // namespace
122*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
123