81 lines · c
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 %t5// RUN: %run %t6// RUN: env HWASAN_OPTIONS=fixed_shadow_base=17592186044416 %run %t7// RUN: env HWASAN_OPTIONS=fixed_shadow_base=4398046511104 %run %t8//9// If -hwasan-mapping-offset is set, then the fixed_shadow_base needs to match.10// RUN: %clang_hwasan %s -mllvm -hwasan-mapping-offset=17592186044416 -o %t11// RUN: env HWASAN_OPTIONS=fixed_shadow_base=17592186044416 %run %t12// RUN: env HWASAN_OPTIONS=fixed_shadow_base=4398046511104 not %run %t13 14// RUN: %clang_hwasan %s -mllvm -hwasan-mapping-offset=4398046511104 -o %t15// RUN: env HWASAN_OPTIONS=fixed_shadow_base=4398046511104 %run %t16// RUN: env HWASAN_OPTIONS=fixed_shadow_base=263878495698944 not %run %t17//18// Note: if fixed_shadow_base is not set, compiler-rt will dynamically choose a19// shadow base, which has a tiny but non-zero probability of matching the20// compiler instrumentation. To avoid test flake, we do not test this case.21//22// Assume 48-bit VMA23// REQUIRES: aarch64-target-arch24//25// REQUIRES: Clang26//27// UNSUPPORTED: android28 29#include <assert.h>30#include <sanitizer/allocator_interface.h>31#include <sanitizer/hwasan_interface.h>32#include <stdio.h>33#include <stdlib.h>34#include <sys/mman.h>35 36int main() {37 __hwasan_enable_allocator_tagging();38 39 // We test that the compiler instrumentation is able to access shadow memory40 // for many different addresses. If we only test a small number of addresses,41 // it might work by chance even if the shadow base does not match between the42 // compiler instrumentation and compiler-rt.43 void **mmaps[256];44 // 48-bit VMA45 for (int i = 0; i < 256; i++) {46 unsigned long long addr = (i * (1ULL << 40));47 48 void *p = mmap((void *)addr, 4096, PROT_READ | PROT_WRITE,49 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);50 // We don't use MAP_FIXED, to avoid overwriting critical memory.51 // However, if we don't get allocated the requested address, it52 // isn't a useful test.53 if ((unsigned long long)p != addr) {54 munmap(p, 4096);55 mmaps[i] = MAP_FAILED;56 } else {57 mmaps[i] = p;58 }59 }60 61 int failures = 0;62 for (int i = 0; i < 256; i++) {63 if (mmaps[i] == MAP_FAILED) {64 failures++;65 } else {66 printf("%d %p\n", i, mmaps[i]);67 munmap(mmaps[i], 4096);68 }69 }70 71 // We expect roughly 17 failures:72 // - the page at address zero73 // - 16 failures because the shadow memory takes up 1/16th of the address space74 // We could also get unlucky e.g., if libraries or binaries are loaded into the75 // exact addresses where we tried to map.76 // To avoid test flake, we allow some margin of error.77 printf("Failed: %d\n", failures);78 assert(failures < 48);79 return 0;80}81