diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -206,11 +206,18 @@ errno = errno_ENOMEM; return (void *)-1; } + __hwasan::TagMemory(reinterpret_cast(addr), length, 0); } return res; } +template +static int munmap_interceptor(Munmap real_munmap, void *addr, SIZE_T length) { + __hwasan::TagMemoryAligned(reinterpret_cast(addr), length, 0); + return real_munmap(addr, length); +} + # define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, \ fd, offset) \ do { \ @@ -218,6 +225,12 @@ return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \ } while (false) +# define COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, munmap, addr, length) \ + do { \ + (void)(ctx); \ + return munmap_interceptor(REAL(munmap), addr, sz); \ + } while (false) + # include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc" # include "sanitizer_common/sanitizer_common_interceptors.inc" diff --git a/compiler-rt/test/hwasan/TestCases/munmap.c b/compiler-rt/test/hwasan/TestCases/munmap.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/munmap.c @@ -0,0 +1,62 @@ +// RUN: %clang_hwasan %s -o %t +// RUN: %run %t 2>&1 + +// REQUIRES: aarch64-target-arch + +#include +#include +#include +#include + +int main(int argc, char **argv) { + int size = 4096; + int tag = 74; + int val = 42; + + // Get any mmaped pointer. + void *r = + mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (r == MAP_FAILED) { + fprintf(stderr, "Failed to mmap.\n"); + abort(); + } + + // Check that the pointer is untagged. + if (r != __hwasan_tag_pointer(r, 0)) { + fprintf(stderr, "Pointer returned by mmap should be untagged.\n"); + return 1; + } + + // Manually tag the pointer and the memory. + __hwasan_tag_memory(r, tag, size); + int *p1 = __hwasan_tag_pointer(r, tag); + + // Check that the pointer and the tag match. + if (__hwasan_test_shadow(p1, size) != -1) { + fprintf(stderr, "Failed to tag.\n"); + return 1; + } + + // First munmmap and then mmap the same pointer using MAP_FIXED. + munmap(r, size); + if (__hwasan_test_shadow(r, size) != -1) { + fprintf(stderr, "Shadow memory was not cleaned by munmap.\n"); + return 1; + } + __hwasan_tag_memory(r, tag, size); + int *p2 = (int *)mmap(r, size, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); + + // Check that the pointer has no tag in it. + if (p2 != r) { + fprintf(stderr, "The mmap pointer has a non-zero tag in it.\n"); + return 1; + } + + // Make sure we can access the shadow with an untagged pointer. + if (__hwasan_test_shadow(p2, size) != -1 ) { + fprintf(stderr, "Shadow memory was not cleaned by mmap.\n"); + return 1; + } + return 0; +}