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