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