xref: /aosp_15_r20/tools/security/sanitizer-status/sanitizer-status.cpp (revision d9ecfb0f4d734c9ce41cde8ac4d585b094fd4222)
1*d9ecfb0fSAndroid Build Coastguard Worker /*
2*d9ecfb0fSAndroid Build Coastguard Worker  * Copyright (C) 2008 The Android Open Source Project
3*d9ecfb0fSAndroid Build Coastguard Worker  *
4*d9ecfb0fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d9ecfb0fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d9ecfb0fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d9ecfb0fSAndroid Build Coastguard Worker  *
8*d9ecfb0fSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*d9ecfb0fSAndroid Build Coastguard Worker  *
10*d9ecfb0fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d9ecfb0fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d9ecfb0fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d9ecfb0fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d9ecfb0fSAndroid Build Coastguard Worker  * limitations under the License.
15*d9ecfb0fSAndroid Build Coastguard Worker  */
16*d9ecfb0fSAndroid Build Coastguard Worker 
17*d9ecfb0fSAndroid Build Coastguard Worker #include <errno.h>
18*d9ecfb0fSAndroid Build Coastguard Worker #include <error.h>
19*d9ecfb0fSAndroid Build Coastguard Worker #include <fcntl.h>
20*d9ecfb0fSAndroid Build Coastguard Worker #include <getopt.h>
21*d9ecfb0fSAndroid Build Coastguard Worker #include <limits.h>
22*d9ecfb0fSAndroid Build Coastguard Worker #include <malloc.h>
23*d9ecfb0fSAndroid Build Coastguard Worker #include <paths.h>
24*d9ecfb0fSAndroid Build Coastguard Worker #include <pthread.h>
25*d9ecfb0fSAndroid Build Coastguard Worker #include <pwd.h>
26*d9ecfb0fSAndroid Build Coastguard Worker #include <stdbool.h>
27*d9ecfb0fSAndroid Build Coastguard Worker #include <stdio.h>
28*d9ecfb0fSAndroid Build Coastguard Worker #include <stdlib.h>
29*d9ecfb0fSAndroid Build Coastguard Worker #include <string.h>
30*d9ecfb0fSAndroid Build Coastguard Worker #include <unistd.h>
31*d9ecfb0fSAndroid Build Coastguard Worker #include <sys/prctl.h>
32*d9ecfb0fSAndroid Build Coastguard Worker #include <sys/types.h>
33*d9ecfb0fSAndroid Build Coastguard Worker #include <sys/wait.h>
34*d9ecfb0fSAndroid Build Coastguard Worker 
35*d9ecfb0fSAndroid Build Coastguard Worker #include <bionic/mte.h>
36*d9ecfb0fSAndroid Build Coastguard Worker 
37*d9ecfb0fSAndroid Build Coastguard Worker char global[32] = {};
38*d9ecfb0fSAndroid Build Coastguard Worker 
39*d9ecfb0fSAndroid Build Coastguard Worker // crashes if built with -fsanitize={address,hwaddress}
test_crash_malloc_overflow()40*d9ecfb0fSAndroid Build Coastguard Worker void test_crash_malloc_overflow() {
41*d9ecfb0fSAndroid Build Coastguard Worker   volatile char* heap = reinterpret_cast<volatile char *>(malloc(32));
42*d9ecfb0fSAndroid Build Coastguard Worker   heap[32] = heap[32];
43*d9ecfb0fSAndroid Build Coastguard Worker   printf("Heap Overflow Test Failed\n");
44*d9ecfb0fSAndroid Build Coastguard Worker }
45*d9ecfb0fSAndroid Build Coastguard Worker 
46*d9ecfb0fSAndroid Build Coastguard Worker // crashes if built with -fsanitize={address,hwaddresss}
test_crash_malloc_uaf()47*d9ecfb0fSAndroid Build Coastguard Worker void test_crash_malloc_uaf() {
48*d9ecfb0fSAndroid Build Coastguard Worker   volatile char* heap = reinterpret_cast<volatile char *>(malloc(32));
49*d9ecfb0fSAndroid Build Coastguard Worker   free((void *)heap);
50*d9ecfb0fSAndroid Build Coastguard Worker   heap[0] = heap[0];
51*d9ecfb0fSAndroid Build Coastguard Worker   printf("Heap UAF Test Failed\n");
52*d9ecfb0fSAndroid Build Coastguard Worker }
53*d9ecfb0fSAndroid Build Coastguard Worker 
54*d9ecfb0fSAndroid Build Coastguard Worker // crashes if built with -fsanitize={address,hwaddress,memtag-stack}
test_crash_stack()55*d9ecfb0fSAndroid Build Coastguard Worker void test_crash_stack() {
56*d9ecfb0fSAndroid Build Coastguard Worker   volatile char stack[32];
57*d9ecfb0fSAndroid Build Coastguard Worker   volatile char* p_stack = stack;
58*d9ecfb0fSAndroid Build Coastguard Worker   p_stack[32] = p_stack[32];
59*d9ecfb0fSAndroid Build Coastguard Worker   printf("(HW)ASAN / Stack MTE: Stack Test Failed\n");
60*d9ecfb0fSAndroid Build Coastguard Worker }
61*d9ecfb0fSAndroid Build Coastguard Worker 
62*d9ecfb0fSAndroid Build Coastguard Worker // crashes if built with -fsanitize={address,hwaddress,memtag-globals}
test_crash_globals()63*d9ecfb0fSAndroid Build Coastguard Worker void test_crash_globals() {
64*d9ecfb0fSAndroid Build Coastguard Worker   volatile char* p_global = global;
65*d9ecfb0fSAndroid Build Coastguard Worker   p_global[32] = p_global[32];
66*d9ecfb0fSAndroid Build Coastguard Worker   printf("(HW)ASAN / Globals MTE: Globals Test Failed\n");
67*d9ecfb0fSAndroid Build Coastguard Worker }
68*d9ecfb0fSAndroid Build Coastguard Worker 
test_crash_pthread_mutex_unlock()69*d9ecfb0fSAndroid Build Coastguard Worker void test_crash_pthread_mutex_unlock() {
70*d9ecfb0fSAndroid Build Coastguard Worker   volatile char* heap = reinterpret_cast<volatile char *>(malloc(32));
71*d9ecfb0fSAndroid Build Coastguard Worker   pthread_mutex_unlock((pthread_mutex_t*)&heap[32]);
72*d9ecfb0fSAndroid Build Coastguard Worker   printf("HWASAN: Libc Test Failed\n");
73*d9ecfb0fSAndroid Build Coastguard Worker }
74*d9ecfb0fSAndroid Build Coastguard Worker 
data_asan_exists()75*d9ecfb0fSAndroid Build Coastguard Worker int data_asan_exists() {
76*d9ecfb0fSAndroid Build Coastguard Worker   int fd = open("/data/asan", O_DIRECTORY | O_PATH | O_CLOEXEC, 0);
77*d9ecfb0fSAndroid Build Coastguard Worker   if(fd < 0) {
78*d9ecfb0fSAndroid Build Coastguard Worker     printf("ASAN: Missing /data/asan\n");
79*d9ecfb0fSAndroid Build Coastguard Worker     return 1;
80*d9ecfb0fSAndroid Build Coastguard Worker   }
81*d9ecfb0fSAndroid Build Coastguard Worker   close(fd);
82*d9ecfb0fSAndroid Build Coastguard Worker   return 0;
83*d9ecfb0fSAndroid Build Coastguard Worker }
84*d9ecfb0fSAndroid Build Coastguard Worker 
85*d9ecfb0fSAndroid Build Coastguard Worker // crashes if built with -fsanitize=memory
test_msan_crash_stack()86*d9ecfb0fSAndroid Build Coastguard Worker void test_msan_crash_stack() {
87*d9ecfb0fSAndroid Build Coastguard Worker   volatile int stack[10];
88*d9ecfb0fSAndroid Build Coastguard Worker   stack[5] = 0;
89*d9ecfb0fSAndroid Build Coastguard Worker   if (stack[0]) { // NOLINT
90*d9ecfb0fSAndroid Build Coastguard Worker     stack[0] = 1;
91*d9ecfb0fSAndroid Build Coastguard Worker   }
92*d9ecfb0fSAndroid Build Coastguard Worker   printf("MSAN: Stack Test Failed\n");
93*d9ecfb0fSAndroid Build Coastguard Worker }
94*d9ecfb0fSAndroid Build Coastguard Worker 
95*d9ecfb0fSAndroid Build Coastguard Worker // crashes if built with -fsanitize=integer
test_integer_overflow()96*d9ecfb0fSAndroid Build Coastguard Worker void test_integer_overflow() {
97*d9ecfb0fSAndroid Build Coastguard Worker   size_t max = (size_t)-1;
98*d9ecfb0fSAndroid Build Coastguard Worker   max++;
99*d9ecfb0fSAndroid Build Coastguard Worker   printf("UBSAN: Integer Overflow Test Failed\n");
100*d9ecfb0fSAndroid Build Coastguard Worker }
101*d9ecfb0fSAndroid Build Coastguard Worker 
102*d9ecfb0fSAndroid Build Coastguard Worker // returns 0 if kcov is enabled
test_kcov()103*d9ecfb0fSAndroid Build Coastguard Worker int test_kcov() {
104*d9ecfb0fSAndroid Build Coastguard Worker   const char* kcov_file = "/sys/kernel/debug/kcov";
105*d9ecfb0fSAndroid Build Coastguard Worker   int fd = open(kcov_file, O_RDWR);
106*d9ecfb0fSAndroid Build Coastguard Worker   if (fd == -1) {
107*d9ecfb0fSAndroid Build Coastguard Worker     printf("KCOV: Could not open %s\n", kcov_file);
108*d9ecfb0fSAndroid Build Coastguard Worker     return 1;
109*d9ecfb0fSAndroid Build Coastguard Worker   }
110*d9ecfb0fSAndroid Build Coastguard Worker   close(fd);
111*d9ecfb0fSAndroid Build Coastguard Worker   return 0;
112*d9ecfb0fSAndroid Build Coastguard Worker }
113*d9ecfb0fSAndroid Build Coastguard Worker 
114*d9ecfb0fSAndroid Build Coastguard Worker // returns 0 if kasan was compiled in
test_kasan()115*d9ecfb0fSAndroid Build Coastguard Worker int test_kasan() {
116*d9ecfb0fSAndroid Build Coastguard Worker   // rely on the exit status of grep to propagate
117*d9ecfb0fSAndroid Build Coastguard Worker   if (system("gzip -d < /proc/config.gz | grep CONFIG_KASAN=y >/dev/null")) {
118*d9ecfb0fSAndroid Build Coastguard Worker     printf("KASAN: CONFIG_KASAN not in /proc/config.gz\n");
119*d9ecfb0fSAndroid Build Coastguard Worker     return 1;
120*d9ecfb0fSAndroid Build Coastguard Worker   }
121*d9ecfb0fSAndroid Build Coastguard Worker   return 0;
122*d9ecfb0fSAndroid Build Coastguard Worker }
123*d9ecfb0fSAndroid Build Coastguard Worker 
124*d9ecfb0fSAndroid Build Coastguard Worker // Number of iterations required to reliably guarantee a GWP-ASan crash.
125*d9ecfb0fSAndroid Build Coastguard Worker // GWP-ASan's sample rate is not truly nondeterministic, it initialises a
126*d9ecfb0fSAndroid Build Coastguard Worker // thread-local counter at 2*SampleRate, and decrements on each malloc(). Once
127*d9ecfb0fSAndroid Build Coastguard Worker // the counter reaches zero, we provide a sampled allocation. GWP-ASan's current
128*d9ecfb0fSAndroid Build Coastguard Worker // default sample rate is 1/5000.
129*d9ecfb0fSAndroid Build Coastguard Worker #define GWP_ASAN_ITERATIONS_TO_ENSURE_CRASH (0x10000)
130*d9ecfb0fSAndroid Build Coastguard Worker 
131*d9ecfb0fSAndroid Build Coastguard Worker // crashes with GWP-ASan
test_crash_gwp_asan()132*d9ecfb0fSAndroid Build Coastguard Worker void test_crash_gwp_asan() {
133*d9ecfb0fSAndroid Build Coastguard Worker   for (unsigned i = 0; i < GWP_ASAN_ITERATIONS_TO_ENSURE_CRASH; ++i ) {
134*d9ecfb0fSAndroid Build Coastguard Worker     volatile char* x = reinterpret_cast<volatile char *>(malloc(1));
135*d9ecfb0fSAndroid Build Coastguard Worker     free((void*) x);
136*d9ecfb0fSAndroid Build Coastguard Worker     *x = 0;
137*d9ecfb0fSAndroid Build Coastguard Worker   }
138*d9ecfb0fSAndroid Build Coastguard Worker   printf("GWP-ASan: Use after Free Failed\n");
139*d9ecfb0fSAndroid Build Coastguard Worker }
140*d9ecfb0fSAndroid Build Coastguard Worker 
141*d9ecfb0fSAndroid Build Coastguard Worker // executes a test that is expected to crash
142*d9ecfb0fSAndroid Build Coastguard Worker // returns 0 if the test crashes
test(void (* function)())143*d9ecfb0fSAndroid Build Coastguard Worker int test(void (*function)()) {
144*d9ecfb0fSAndroid Build Coastguard Worker   fflush(stdout);
145*d9ecfb0fSAndroid Build Coastguard Worker 
146*d9ecfb0fSAndroid Build Coastguard Worker   pid_t child = fork();
147*d9ecfb0fSAndroid Build Coastguard Worker   int status = 0;
148*d9ecfb0fSAndroid Build Coastguard Worker 
149*d9ecfb0fSAndroid Build Coastguard Worker   if (child == -1) {
150*d9ecfb0fSAndroid Build Coastguard Worker     perror("fork");
151*d9ecfb0fSAndroid Build Coastguard Worker     exit(1);
152*d9ecfb0fSAndroid Build Coastguard Worker   }
153*d9ecfb0fSAndroid Build Coastguard Worker 
154*d9ecfb0fSAndroid Build Coastguard Worker   if (child == 0) {
155*d9ecfb0fSAndroid Build Coastguard Worker     // Silence the ASAN report that is generated
156*d9ecfb0fSAndroid Build Coastguard Worker     close(2);
157*d9ecfb0fSAndroid Build Coastguard Worker 
158*d9ecfb0fSAndroid Build Coastguard Worker     // Invoke the target function.  If it does not crash, terminate the process.
159*d9ecfb0fSAndroid Build Coastguard Worker     function();
160*d9ecfb0fSAndroid Build Coastguard Worker     exit(EXIT_SUCCESS);
161*d9ecfb0fSAndroid Build Coastguard Worker   }
162*d9ecfb0fSAndroid Build Coastguard Worker 
163*d9ecfb0fSAndroid Build Coastguard Worker   // Wait for the child to either crash, or exit cleanly
164*d9ecfb0fSAndroid Build Coastguard Worker   while (child == waitpid(child, &status, 0)) {
165*d9ecfb0fSAndroid Build Coastguard Worker     if (!WIFEXITED(status))
166*d9ecfb0fSAndroid Build Coastguard Worker       continue;
167*d9ecfb0fSAndroid Build Coastguard Worker     if (WEXITSTATUS(status) == EXIT_SUCCESS)
168*d9ecfb0fSAndroid Build Coastguard Worker       return 1;
169*d9ecfb0fSAndroid Build Coastguard Worker     break;
170*d9ecfb0fSAndroid Build Coastguard Worker   }
171*d9ecfb0fSAndroid Build Coastguard Worker   return 0;
172*d9ecfb0fSAndroid Build Coastguard Worker }
173*d9ecfb0fSAndroid Build Coastguard Worker 
have_option(const char * option,const char ** argv,const int argc)174*d9ecfb0fSAndroid Build Coastguard Worker int have_option(const char* option, const char** argv, const int argc) {
175*d9ecfb0fSAndroid Build Coastguard Worker   for (int i = 1; i < argc; i++)
176*d9ecfb0fSAndroid Build Coastguard Worker     if (!strcmp(option, argv[i]))
177*d9ecfb0fSAndroid Build Coastguard Worker       return 1;
178*d9ecfb0fSAndroid Build Coastguard Worker   return 0;
179*d9ecfb0fSAndroid Build Coastguard Worker }
180*d9ecfb0fSAndroid Build Coastguard Worker 
main(int argc,const char ** argv)181*d9ecfb0fSAndroid Build Coastguard Worker int main(int argc, const char** argv) {
182*d9ecfb0fSAndroid Build Coastguard Worker   int test_everything = 0;
183*d9ecfb0fSAndroid Build Coastguard Worker   int failures = 0;
184*d9ecfb0fSAndroid Build Coastguard Worker 
185*d9ecfb0fSAndroid Build Coastguard Worker   if (argc <= 1)
186*d9ecfb0fSAndroid Build Coastguard Worker     test_everything = 1;
187*d9ecfb0fSAndroid Build Coastguard Worker 
188*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("asan", argv, argc)) {
189*d9ecfb0fSAndroid Build Coastguard Worker     int asan_failures = 0;
190*d9ecfb0fSAndroid Build Coastguard Worker 
191*d9ecfb0fSAndroid Build Coastguard Worker #if !__has_feature(address_sanitizer)
192*d9ecfb0fSAndroid Build Coastguard Worker     asan_failures += 1;
193*d9ecfb0fSAndroid Build Coastguard Worker     printf("ASAN: Compiler flags failed!\n");
194*d9ecfb0fSAndroid Build Coastguard Worker #endif
195*d9ecfb0fSAndroid Build Coastguard Worker 
196*d9ecfb0fSAndroid Build Coastguard Worker     asan_failures += test(test_crash_malloc_overflow);
197*d9ecfb0fSAndroid Build Coastguard Worker     asan_failures += test(test_crash_malloc_uaf);
198*d9ecfb0fSAndroid Build Coastguard Worker     asan_failures += test(test_crash_stack);
199*d9ecfb0fSAndroid Build Coastguard Worker     asan_failures += data_asan_exists();
200*d9ecfb0fSAndroid Build Coastguard Worker 
201*d9ecfb0fSAndroid Build Coastguard Worker     if (!asan_failures)
202*d9ecfb0fSAndroid Build Coastguard Worker       printf("ASAN: OK\n");
203*d9ecfb0fSAndroid Build Coastguard Worker 
204*d9ecfb0fSAndroid Build Coastguard Worker     failures += asan_failures;
205*d9ecfb0fSAndroid Build Coastguard Worker   }
206*d9ecfb0fSAndroid Build Coastguard Worker 
207*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("hwasan", argv, argc)) {
208*d9ecfb0fSAndroid Build Coastguard Worker     int hwasan_failures = 0;
209*d9ecfb0fSAndroid Build Coastguard Worker 
210*d9ecfb0fSAndroid Build Coastguard Worker #if !__has_feature(hwaddress_sanitizer)
211*d9ecfb0fSAndroid Build Coastguard Worker     hwasan_failures += 1;
212*d9ecfb0fSAndroid Build Coastguard Worker     printf("HWASAN: Compiler flags failed!\n");
213*d9ecfb0fSAndroid Build Coastguard Worker #endif
214*d9ecfb0fSAndroid Build Coastguard Worker 
215*d9ecfb0fSAndroid Build Coastguard Worker     hwasan_failures += test(test_crash_malloc_overflow);
216*d9ecfb0fSAndroid Build Coastguard Worker     hwasan_failures += test(test_crash_malloc_uaf);
217*d9ecfb0fSAndroid Build Coastguard Worker     hwasan_failures += test(test_crash_stack);
218*d9ecfb0fSAndroid Build Coastguard Worker     hwasan_failures += test(test_crash_pthread_mutex_unlock);
219*d9ecfb0fSAndroid Build Coastguard Worker     hwasan_failures += test(test_crash_globals);
220*d9ecfb0fSAndroid Build Coastguard Worker 
221*d9ecfb0fSAndroid Build Coastguard Worker     if (!hwasan_failures)
222*d9ecfb0fSAndroid Build Coastguard Worker       printf("HWASAN: OK\n");
223*d9ecfb0fSAndroid Build Coastguard Worker 
224*d9ecfb0fSAndroid Build Coastguard Worker     failures += hwasan_failures;
225*d9ecfb0fSAndroid Build Coastguard Worker   }
226*d9ecfb0fSAndroid Build Coastguard Worker 
227*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("msan", argv, argc)) {
228*d9ecfb0fSAndroid Build Coastguard Worker     int msan_failures = 0;
229*d9ecfb0fSAndroid Build Coastguard Worker 
230*d9ecfb0fSAndroid Build Coastguard Worker     msan_failures += test(test_msan_crash_stack);
231*d9ecfb0fSAndroid Build Coastguard Worker 
232*d9ecfb0fSAndroid Build Coastguard Worker     if (!msan_failures)
233*d9ecfb0fSAndroid Build Coastguard Worker       printf("MSAN: OK\n");
234*d9ecfb0fSAndroid Build Coastguard Worker 
235*d9ecfb0fSAndroid Build Coastguard Worker     failures += msan_failures;
236*d9ecfb0fSAndroid Build Coastguard Worker   }
237*d9ecfb0fSAndroid Build Coastguard Worker 
238*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("kasan", argv, argc)) {
239*d9ecfb0fSAndroid Build Coastguard Worker     int kasan_failures = 0;
240*d9ecfb0fSAndroid Build Coastguard Worker 
241*d9ecfb0fSAndroid Build Coastguard Worker     kasan_failures += test_kasan();
242*d9ecfb0fSAndroid Build Coastguard Worker 
243*d9ecfb0fSAndroid Build Coastguard Worker     if(!kasan_failures)
244*d9ecfb0fSAndroid Build Coastguard Worker       printf("KASAN: OK\n");
245*d9ecfb0fSAndroid Build Coastguard Worker 
246*d9ecfb0fSAndroid Build Coastguard Worker     failures += kasan_failures;
247*d9ecfb0fSAndroid Build Coastguard Worker   }
248*d9ecfb0fSAndroid Build Coastguard Worker 
249*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("kcov", argv, argc)) {
250*d9ecfb0fSAndroid Build Coastguard Worker     int kcov_failures = 0;
251*d9ecfb0fSAndroid Build Coastguard Worker 
252*d9ecfb0fSAndroid Build Coastguard Worker     kcov_failures += test_kcov();
253*d9ecfb0fSAndroid Build Coastguard Worker 
254*d9ecfb0fSAndroid Build Coastguard Worker     if (!kcov_failures)
255*d9ecfb0fSAndroid Build Coastguard Worker       printf("KCOV: OK\n");
256*d9ecfb0fSAndroid Build Coastguard Worker 
257*d9ecfb0fSAndroid Build Coastguard Worker     failures += kcov_failures;
258*d9ecfb0fSAndroid Build Coastguard Worker   }
259*d9ecfb0fSAndroid Build Coastguard Worker 
260*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("ubsan", argv, argc)) {
261*d9ecfb0fSAndroid Build Coastguard Worker     int ubsan_failures = 0;
262*d9ecfb0fSAndroid Build Coastguard Worker 
263*d9ecfb0fSAndroid Build Coastguard Worker     ubsan_failures += test(test_integer_overflow);
264*d9ecfb0fSAndroid Build Coastguard Worker 
265*d9ecfb0fSAndroid Build Coastguard Worker     if (!ubsan_failures)
266*d9ecfb0fSAndroid Build Coastguard Worker       printf("UBSAN: OK\n");
267*d9ecfb0fSAndroid Build Coastguard Worker 
268*d9ecfb0fSAndroid Build Coastguard Worker     failures += ubsan_failures;
269*d9ecfb0fSAndroid Build Coastguard Worker   }
270*d9ecfb0fSAndroid Build Coastguard Worker 
271*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("gwp_asan", argv, argc)) {
272*d9ecfb0fSAndroid Build Coastguard Worker     int gwp_asan_failures = 0;
273*d9ecfb0fSAndroid Build Coastguard Worker 
274*d9ecfb0fSAndroid Build Coastguard Worker     gwp_asan_failures += test(test_crash_gwp_asan);
275*d9ecfb0fSAndroid Build Coastguard Worker 
276*d9ecfb0fSAndroid Build Coastguard Worker     if (!gwp_asan_failures)
277*d9ecfb0fSAndroid Build Coastguard Worker       printf("GWP-ASan: OK\n");
278*d9ecfb0fSAndroid Build Coastguard Worker 
279*d9ecfb0fSAndroid Build Coastguard Worker     failures += gwp_asan_failures;
280*d9ecfb0fSAndroid Build Coastguard Worker   }
281*d9ecfb0fSAndroid Build Coastguard Worker 
282*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("mte", argv, argc)) {
283*d9ecfb0fSAndroid Build Coastguard Worker     int mte_failures = 0;
284*d9ecfb0fSAndroid Build Coastguard Worker 
285*d9ecfb0fSAndroid Build Coastguard Worker     if (!(mte_supported() && !__has_feature(address_sanitizer) &&
286*d9ecfb0fSAndroid Build Coastguard Worker           !__has_feature(hwaddress_sanitizer))) {
287*d9ecfb0fSAndroid Build Coastguard Worker       mte_failures += 1;
288*d9ecfb0fSAndroid Build Coastguard Worker       printf("MTE: Not supported\n");
289*d9ecfb0fSAndroid Build Coastguard Worker     }
290*d9ecfb0fSAndroid Build Coastguard Worker 
291*d9ecfb0fSAndroid Build Coastguard Worker     mte_failures += test(test_crash_malloc_overflow);
292*d9ecfb0fSAndroid Build Coastguard Worker     mte_failures += test(test_crash_malloc_uaf);
293*d9ecfb0fSAndroid Build Coastguard Worker 
294*d9ecfb0fSAndroid Build Coastguard Worker     int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
295*d9ecfb0fSAndroid Build Coastguard Worker     if (tagged_addr_ctrl < 0) {
296*d9ecfb0fSAndroid Build Coastguard Worker       mte_failures += 1;
297*d9ecfb0fSAndroid Build Coastguard Worker       printf("MTE: PR_GET_TAGGED_ADDR_CTRL failed\n");
298*d9ecfb0fSAndroid Build Coastguard Worker     }
299*d9ecfb0fSAndroid Build Coastguard Worker 
300*d9ecfb0fSAndroid Build Coastguard Worker     HeapTaggingLevel heap_tagging_level = M_HEAP_TAGGING_LEVEL_SYNC;
301*d9ecfb0fSAndroid Build Coastguard Worker     if (mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level) == 0) {
302*d9ecfb0fSAndroid Build Coastguard Worker       mte_failures += 1;
303*d9ecfb0fSAndroid Build Coastguard Worker       printf("MTE: mallopt failed\n");
304*d9ecfb0fSAndroid Build Coastguard Worker     }
305*d9ecfb0fSAndroid Build Coastguard Worker 
306*d9ecfb0fSAndroid Build Coastguard Worker     mte_failures += test(test_crash_malloc_overflow);
307*d9ecfb0fSAndroid Build Coastguard Worker     mte_failures += test(test_crash_malloc_uaf);
308*d9ecfb0fSAndroid Build Coastguard Worker 
309*d9ecfb0fSAndroid Build Coastguard Worker     if (!mte_failures)
310*d9ecfb0fSAndroid Build Coastguard Worker       printf("MTE: OK\n");
311*d9ecfb0fSAndroid Build Coastguard Worker 
312*d9ecfb0fSAndroid Build Coastguard Worker     failures += mte_failures;
313*d9ecfb0fSAndroid Build Coastguard Worker   }
314*d9ecfb0fSAndroid Build Coastguard Worker 
315*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("stack_mte", argv, argc)) {
316*d9ecfb0fSAndroid Build Coastguard Worker     int stack_mte_failures = 0;
317*d9ecfb0fSAndroid Build Coastguard Worker 
318*d9ecfb0fSAndroid Build Coastguard Worker     if (!(mte_supported() && !__has_feature(address_sanitizer) &&
319*d9ecfb0fSAndroid Build Coastguard Worker           !__has_feature(hwaddress_sanitizer))) {
320*d9ecfb0fSAndroid Build Coastguard Worker       stack_mte_failures += 1;
321*d9ecfb0fSAndroid Build Coastguard Worker       printf("MTE: Not supported\n");
322*d9ecfb0fSAndroid Build Coastguard Worker     }
323*d9ecfb0fSAndroid Build Coastguard Worker 
324*d9ecfb0fSAndroid Build Coastguard Worker     stack_mte_failures += test(test_crash_stack);
325*d9ecfb0fSAndroid Build Coastguard Worker 
326*d9ecfb0fSAndroid Build Coastguard Worker     if (!stack_mte_failures)
327*d9ecfb0fSAndroid Build Coastguard Worker       printf("Stack MTE: OK\n");
328*d9ecfb0fSAndroid Build Coastguard Worker 
329*d9ecfb0fSAndroid Build Coastguard Worker     failures += stack_mte_failures;
330*d9ecfb0fSAndroid Build Coastguard Worker   }
331*d9ecfb0fSAndroid Build Coastguard Worker 
332*d9ecfb0fSAndroid Build Coastguard Worker   if (test_everything || have_option("globals_mte", argv, argc)) {
333*d9ecfb0fSAndroid Build Coastguard Worker     int globals_mte_failures = 0;
334*d9ecfb0fSAndroid Build Coastguard Worker 
335*d9ecfb0fSAndroid Build Coastguard Worker     if (!(mte_supported() && !__has_feature(address_sanitizer) &&
336*d9ecfb0fSAndroid Build Coastguard Worker           !__has_feature(hwaddress_sanitizer))) {
337*d9ecfb0fSAndroid Build Coastguard Worker       globals_mte_failures += 1;
338*d9ecfb0fSAndroid Build Coastguard Worker       printf("MTE: Not supported\n");
339*d9ecfb0fSAndroid Build Coastguard Worker     }
340*d9ecfb0fSAndroid Build Coastguard Worker 
341*d9ecfb0fSAndroid Build Coastguard Worker     globals_mte_failures += test(test_crash_globals);
342*d9ecfb0fSAndroid Build Coastguard Worker 
343*d9ecfb0fSAndroid Build Coastguard Worker     if (!globals_mte_failures)
344*d9ecfb0fSAndroid Build Coastguard Worker       printf("Globals MTE: OK\n");
345*d9ecfb0fSAndroid Build Coastguard Worker 
346*d9ecfb0fSAndroid Build Coastguard Worker     failures += globals_mte_failures;
347*d9ecfb0fSAndroid Build Coastguard Worker   }
348*d9ecfb0fSAndroid Build Coastguard Worker 
349*d9ecfb0fSAndroid Build Coastguard Worker   return failures > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
350*d9ecfb0fSAndroid Build Coastguard Worker }
351