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