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 @@ -296,6 +296,11 @@ return 0; } +static bool IsShadow(uptr p) { + return (kLowShadowStart <= p && p < kLowShadowEnd) || + (kHighShadowStart <= p && p < kHighShadowEnd); +} + void PrintAddressDescription( uptr tagged_addr, uptr access_size, StackAllocationsRingBuffer *current_stack_allocations) { @@ -325,12 +330,12 @@ tag_t *tag_ptr = reinterpret_cast(MemToShadow(untagged_addr)); tag_t *candidate = nullptr, *left = tag_ptr, *right = tag_ptr; for (int i = 0; i < 1000; i++) { - if (TagsEqual(addr_tag, left)) { + if (IsShadow(reinterpret_cast(left)) && TagsEqual(addr_tag, left)) { candidate = left; break; } --left; - if (TagsEqual(addr_tag, right)) { + if (IsShadow(reinterpret_cast(right)) && TagsEqual(addr_tag, right)) { candidate = right; break; } diff --git a/compiler-rt/test/hwasan/TestCases/tag-mismatch-border-address.c b/compiler-rt/test/hwasan/TestCases/tag-mismatch-border-address.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/tag-mismatch-border-address.c @@ -0,0 +1,30 @@ +// Make sure we do not segfault when checking an address close to kLowMemEnd. +// RUN: %clang_hwasan %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK + +// REQUIRES: stable-runtime +// REQUIRES: aarch64-target-arch + +#include +#include +#include +#include + +static volatile char sink; +extern void *__hwasan_shadow_memory_dynamic_address; + +int main(int argc, char **argv) { + void *high_addr = (char *)__hwasan_shadow_memory_dynamic_address - 0x1000; + void *r = mmap(high_addr, 4096, PROT_READ, MAP_FIXED | MAP_ANON | MAP_PRIVATE, + -1, 0); + if (r == MAP_FAILED) { + fprintf(stderr, "Failed to mmap\n"); + abort(); + } + volatile char *x = (char *)__hwasan_tag_pointer(r, 4); + sink = *x; +} + +// CHECK-NOT: Failed to mmap +// CHECK-NOT: Segmentation fault +// CHECK-NOT: SEGV