diff --git a/compiler-rt/include/sanitizer/hwasan_interface.h b/compiler-rt/include/sanitizer/hwasan_interface.h --- a/compiler-rt/include/sanitizer/hwasan_interface.h +++ b/compiler-rt/include/sanitizer/hwasan_interface.h @@ -40,6 +40,12 @@ void __hwasan_tag_memory(const volatile void *p, unsigned char tag, size_t size); + // Return an untagged version of the provided pointer. Provided to enable + // architecture- and runtime-independent untagging. Note that a tagged and an + // untagged pointer may be pointers to different memory, as is the case on x64 + // with page aliasing. + void *__hwasan_untag_pointer(const volatile void *p); + /// Set pointer tag. Previous tag is lost. void *__hwasan_tag_pointer(const volatile void *p, unsigned char tag); diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -448,6 +448,8 @@ TagMemoryAligned(p, sz, tag); } +uptr __hwasan_untag_pointer(uptr p) { return UntagAddr(p); } + uptr __hwasan_tag_pointer(uptr p, u8 tag) { return AddTagToPointer(p, tag); } diff --git a/compiler-rt/lib/hwasan/hwasan_interface_internal.h b/compiler-rt/lib/hwasan/hwasan_interface_internal.h --- a/compiler-rt/lib/hwasan/hwasan_interface_internal.h +++ b/compiler-rt/lib/hwasan/hwasan_interface_internal.h @@ -105,6 +105,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __hwasan_tag_memory(uptr p, u8 tag, uptr sz); +SANITIZER_INTERFACE_ATTRIBUTE +uptr __hwasan_untag_pointer(uptr p); + SANITIZER_INTERFACE_ATTRIBUTE uptr __hwasan_tag_pointer(uptr p, u8 tag); diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -462,7 +462,7 @@ InternalScopedString s; for (tag_t *row = beg_row; row < end_row; row += row_len) { s.append("%s", row == center_row_beg ? "=>" : " "); - s.append("%p:", row); + s.append("%p:", ShadowToMem(reinterpret_cast(row))); for (uptr i = 0; i < row_len; i++) { s.append("%s", row + i == tag_ptr ? "[" : " "); print_tag(s, &row[i]); diff --git a/compiler-rt/test/hwasan/TestCases/tag-uses-memory-address.cpp b/compiler-rt/test/hwasan/TestCases/tag-uses-memory-address.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/tag-uses-memory-address.cpp @@ -0,0 +1,30 @@ +// RUN: %clangxx_hwasan -DTEST_UAF %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_hwasan -DTEST_INVALID_FREE %s -o %t && not %run %t 2>&1 | FileCheck %s + +#include +#include +#include + +#include + +int main() { + __hwasan_enable_allocator_tagging(); + volatile char *alloc = (volatile char *)memalign(4096, 4096); + fprintf(stderr, "Memory pointer: %p\n", __hwasan_tag_pointer(alloc, 0)); + free((void *)alloc); + +#ifdef TEST_UAF + *alloc = 1; +#elif TEST_INVALID_FREE + free((void *)alloc); +#else // TEST_* +#error Missing test define. +#endif + + // CHECK: Memory pointer: 0x[[PTR:[0-9a-f]+]] + // CHECK: Memory tags around the buggy address + // CHECK: =>0x{{0*}}[[PTR]]: + + fprintf(stderr, "success?\n"); + return 0; +}