diff --git a/compiler-rt/lib/hwasan/hwasan_mapping.h b/compiler-rt/lib/hwasan/hwasan_mapping.h --- a/compiler-rt/lib/hwasan/hwasan_mapping.h +++ b/compiler-rt/lib/hwasan/hwasan_mapping.h @@ -65,6 +65,11 @@ bool MemIsApp(uptr p); +inline bool MemIsShadow(uptr p) { + return (kLowShadowStart <= p && p <= kLowShadowEnd) || + (kHighShadowStart <= p && p <= kHighShadowEnd); +} + } // namespace __hwasan #endif // HWASAN_MAPPING_H 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 @@ -395,12 +395,14 @@ tag_t *candidate = nullptr, *left = tag_ptr, *right = tag_ptr; uptr candidate_distance = 0; for (; candidate_distance < 1000; candidate_distance++) { - if (TagsEqual(addr_tag, left)) { + if (MemIsShadow(reinterpret_cast(left)) && + TagsEqual(addr_tag, left)) { candidate = left; break; } --left; - if (TagsEqual(addr_tag, right)) { + if (MemIsShadow(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