HWASan support in ART.
Two small tweaks:
* The highest 8 bits of a pointer in hwasan contain a random tag which needs to
be removed before comparing _unrelated_ pointers.
* Annotate DoLongJump. HWASan needs to re-tag the newly unallocated stack space
to match SP. This is similar to ASan annotation (__asan_handle_noreturn), but
more precise - HWASan needs to know the destination SP address because it can
not conservatively "unpoison" the entire stack like ASan does.
Bug: 112438058
Test: mmm SANITIZE_TARGET=hwaddress
Change-Id: I9f9d92495b3a4b2637e48c7af1b614e8d1db8ea0
diff --git a/runtime/arch/arm64/context_arm64.cc b/runtime/arch/arm64/context_arm64.cc
index 0f0814a..16f4792 100644
--- a/runtime/arch/arm64/context_arm64.cc
+++ b/runtime/arch/arm64/context_arm64.cc
@@ -23,6 +23,12 @@
#include "quick/quick_method_frame_info.h"
#include "thread-current-inl.h"
+#if __has_feature(hwaddress_sanitizer)
+#include <sanitizer/hwasan_interface.h>
+#else
+#define __hwasan_handle_longjmp(sp)
+#endif
+
namespace art {
namespace arm64 {
@@ -139,6 +145,8 @@
}
// Ensure the Thread Register contains the address of the current thread.
DCHECK_EQ(reinterpret_cast<uintptr_t>(Thread::Current()), gprs[TR]);
+ // Tell HWASan about the new stack top.
+ __hwasan_handle_longjmp(reinterpret_cast<void*>(gprs[SP]));
// The Marking Register will be updated by art_quick_do_long_jump.
art_quick_do_long_jump(gprs, fprs);
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index df7f19d..abc1bfd 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -25,6 +25,12 @@
#include <sys/resource.h>
#include <sys/time.h>
+#if __has_feature(hwaddress_sanitizer)
+#include <sanitizer/hwasan_interface.h>
+#else
+#define __hwasan_tag_pointer(p, t) (p)
+#endif
+
#include <algorithm>
#include <bitset>
#include <cerrno>
@@ -623,7 +629,9 @@
#endif
volatile char space[kPageSize - (kAsanMultiplier * 256)];
char sink ATTRIBUTE_UNUSED = space[zero]; // NOLINT
- if (reinterpret_cast<uintptr_t>(space) >= target + kPageSize) {
+ // Remove tag from the pointer. Nop in non-hwasan builds.
+ uintptr_t addr = reinterpret_cast<uintptr_t>(__hwasan_tag_pointer(space, 0));
+ if (addr >= target + kPageSize) {
Touch(target);
}
zero *= 2; // Try to avoid tail recursion.