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

source code of compiler-rt/test/hwasan/TestCases/Linux/fixed-shadow.c