xref: /llvm-project/compiler-rt/test/hwasan/TestCases/Linux/fixed-shadow.c (revision 144dae207a3b1750ec94553248bf44c359b6d452)
10ca05e82SThurston Dang // Test fixed shadow base functionality.
20ca05e82SThurston Dang //
30ca05e82SThurston Dang // Default compiler instrumentation works with any shadow base (dynamic or fixed).
4*144dae20SVitaly Buka // RUN: %clang_hwasan %s -o %t
5*144dae20SVitaly Buka // RUN: %run %t
6*144dae20SVitaly Buka // RUN: HWASAN_OPTIONS=fixed_shadow_base=263878495698944 %run %t 2>%t.out || (cat %t.out | FileCheck %s)
7*144dae20SVitaly Buka // RUN: HWASAN_OPTIONS=fixed_shadow_base=4398046511104 %run %t
80ca05e82SThurston Dang //
90ca05e82SThurston Dang // If -hwasan-mapping-offset is set, then the fixed_shadow_base needs to match.
10*144dae20SVitaly Buka // RUN: %clang_hwasan %s -mllvm -hwasan-mapping-offset=263878495698944 -o %t
11*144dae20SVitaly Buka // RUN: HWASAN_OPTIONS=fixed_shadow_base=263878495698944 %run %t 2>%t.out || (cat %t.out | FileCheck %s)
12*144dae20SVitaly Buka // RUN: HWASAN_OPTIONS=fixed_shadow_base=4398046511104 not %run %t
13*144dae20SVitaly Buka 
14*144dae20SVitaly Buka // RUN: %clang_hwasan %s -mllvm -hwasan-mapping-offset=4398046511104 -o %t
15*144dae20SVitaly Buka // RUN: HWASAN_OPTIONS=fixed_shadow_base=4398046511104 %run %t
16*144dae20SVitaly Buka // RUN: HWASAN_OPTIONS=fixed_shadow_base=263878495698944 not %run %t
170ca05e82SThurston Dang //
180ca05e82SThurston Dang // Note: if fixed_shadow_base is not set, compiler-rt will dynamically choose a
190ca05e82SThurston Dang // shadow base, which has a tiny but non-zero probability of matching the
200ca05e82SThurston Dang // compiler instrumentation. To avoid test flake, we do not test this case.
210ca05e82SThurston Dang //
220ca05e82SThurston Dang // Assume 48-bit VMA
230ca05e82SThurston Dang // REQUIRES: aarch64-target-arch
240ca05e82SThurston Dang //
250ca05e82SThurston Dang // REQUIRES: Clang
260ca05e82SThurston Dang //
270ca05e82SThurston Dang // UNSUPPORTED: android
280ca05e82SThurston Dang 
29*144dae20SVitaly Buka // CHECK: FATAL: HWAddressSanitizer: Shadow range {{.*}} is not available
3084682ad8SVitaly Buka 
310ca05e82SThurston Dang #include <assert.h>
320ca05e82SThurston Dang #include <sanitizer/allocator_interface.h>
330ca05e82SThurston Dang #include <sanitizer/hwasan_interface.h>
340ca05e82SThurston Dang #include <stdio.h>
350ca05e82SThurston Dang #include <stdlib.h>
360ca05e82SThurston Dang #include <sys/mman.h>
370ca05e82SThurston Dang 
380ca05e82SThurston Dang int main() {
390ca05e82SThurston Dang   __hwasan_enable_allocator_tagging();
400ca05e82SThurston Dang 
410ca05e82SThurston Dang   // We test that the compiler instrumentation is able to access shadow memory
420ca05e82SThurston Dang   // for many different addresses. If we only test a small number of addresses,
430ca05e82SThurston Dang   // it might work by chance even if the shadow base does not match between the
440ca05e82SThurston Dang   // compiler instrumentation and compiler-rt.
450ca05e82SThurston Dang   void **mmaps[256];
460ca05e82SThurston Dang   // 48-bit VMA
470ca05e82SThurston Dang   for (int i = 0; i < 256; i++) {
480ca05e82SThurston Dang     unsigned long long addr = (i * (1ULL << 40));
490ca05e82SThurston Dang 
500ca05e82SThurston Dang     void *p = mmap((void *)addr, 4096, PROT_READ | PROT_WRITE,
510ca05e82SThurston Dang                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
520ca05e82SThurston Dang     // We don't use MAP_FIXED, to avoid overwriting critical memory.
530ca05e82SThurston Dang     // However, if we don't get allocated the requested address, it
540ca05e82SThurston Dang     // isn't a useful test.
550ca05e82SThurston Dang     if ((unsigned long long)p != addr) {
560ca05e82SThurston Dang       munmap(p, 4096);
570ca05e82SThurston Dang       mmaps[i] = MAP_FAILED;
580ca05e82SThurston Dang     } else {
590ca05e82SThurston Dang       mmaps[i] = p;
600ca05e82SThurston Dang     }
610ca05e82SThurston Dang   }
620ca05e82SThurston Dang 
630ca05e82SThurston Dang   int failures = 0;
640ca05e82SThurston Dang   for (int i = 0; i < 256; i++) {
650ca05e82SThurston Dang     if (mmaps[i] == MAP_FAILED) {
660ca05e82SThurston Dang       failures++;
670ca05e82SThurston Dang     } else {
680ca05e82SThurston Dang       printf("%d %p\n", i, mmaps[i]);
690ca05e82SThurston Dang       munmap(mmaps[i], 4096);
700ca05e82SThurston Dang     }
710ca05e82SThurston Dang   }
720ca05e82SThurston Dang 
730ca05e82SThurston Dang   // We expect roughly 17 failures:
740ca05e82SThurston Dang   // - the page at address zero
750ca05e82SThurston Dang   // - 16 failures because the shadow memory takes up 1/16th of the address space
760ca05e82SThurston Dang   // We could also get unlucky e.g., if libraries or binaries are loaded into the
770ca05e82SThurston Dang   // exact addresses where we tried to map.
780ca05e82SThurston Dang   // To avoid test flake, we allow some margin of error.
790ca05e82SThurston Dang   printf("Failed: %d\n", failures);
800ca05e82SThurston Dang   assert(failures < 48);
810ca05e82SThurston Dang   return 0;
820ca05e82SThurston Dang }
83