xref: /llvm-project/compiler-rt/test/hwasan/TestCases/Linux/fixed-shadow.c (revision 144dae207a3b1750ec94553248bf44c359b6d452)
1 // Test fixed shadow base functionality.
2 //
3 // Default compiler instrumentation works with any shadow base (dynamic or fixed).
4 // RUN: %clang_hwasan %s -o %t
5 // RUN: %run %t
6 // RUN: HWASAN_OPTIONS=fixed_shadow_base=263878495698944 %run %t 2>%t.out || (cat %t.out | FileCheck %s)
7 // RUN: HWASAN_OPTIONS=fixed_shadow_base=4398046511104 %run %t
8 //
9 // If -hwasan-mapping-offset is set, then the fixed_shadow_base needs to match.
10 // RUN: %clang_hwasan %s -mllvm -hwasan-mapping-offset=263878495698944 -o %t
11 // RUN: HWASAN_OPTIONS=fixed_shadow_base=263878495698944 %run %t 2>%t.out || (cat %t.out | FileCheck %s)
12 // RUN: HWASAN_OPTIONS=fixed_shadow_base=4398046511104 not %run %t
13 
14 // RUN: %clang_hwasan %s -mllvm -hwasan-mapping-offset=4398046511104 -o %t
15 // RUN: HWASAN_OPTIONS=fixed_shadow_base=4398046511104 %run %t
16 // RUN: HWASAN_OPTIONS=fixed_shadow_base=263878495698944 not %run %t
17 //
18 // Note: if fixed_shadow_base is not set, compiler-rt will dynamically choose a
19 // shadow base, which has a tiny but non-zero probability of matching the
20 // compiler instrumentation. To avoid test flake, we do not test this case.
21 //
22 // Assume 48-bit VMA
23 // REQUIRES: aarch64-target-arch
24 //
25 // REQUIRES: Clang
26 //
27 // UNSUPPORTED: android
28 
29 // CHECK: FATAL: HWAddressSanitizer: Shadow range {{.*}} is not available
30 
31 #include <assert.h>
32 #include <sanitizer/allocator_interface.h>
33 #include <sanitizer/hwasan_interface.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/mman.h>
37 
38 int main() {
39   __hwasan_enable_allocator_tagging();
40 
41   // We test that the compiler instrumentation is able to access shadow memory
42   // for many different addresses. If we only test a small number of addresses,
43   // it might work by chance even if the shadow base does not match between the
44   // compiler instrumentation and compiler-rt.
45   void **mmaps[256];
46   // 48-bit VMA
47   for (int i = 0; i < 256; i++) {
48     unsigned long long addr = (i * (1ULL << 40));
49 
50     void *p = mmap((void *)addr, 4096, PROT_READ | PROT_WRITE,
51                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
52     // We don't use MAP_FIXED, to avoid overwriting critical memory.
53     // However, if we don't get allocated the requested address, it
54     // isn't a useful test.
55     if ((unsigned long long)p != addr) {
56       munmap(p, 4096);
57       mmaps[i] = MAP_FAILED;
58     } else {
59       mmaps[i] = p;
60     }
61   }
62 
63   int failures = 0;
64   for (int i = 0; i < 256; i++) {
65     if (mmaps[i] == MAP_FAILED) {
66       failures++;
67     } else {
68       printf("%d %p\n", i, mmaps[i]);
69       munmap(mmaps[i], 4096);
70     }
71   }
72 
73   // We expect roughly 17 failures:
74   // - the page at address zero
75   // - 16 failures because the shadow memory takes up 1/16th of the address space
76   // We could also get unlucky e.g., if libraries or binaries are loaded into the
77   // exact addresses where we tried to map.
78   // To avoid test flake, we allow some margin of error.
79   printf("Failed: %d\n", failures);
80   assert(failures < 48);
81   return 0;
82 }
83