[llvm-branch-commits] [compiler-rt] [hwasan] Add `__hwasan_get_tag_from_pointer` (PR #75267)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 12 17:02:37 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Vitaly Buka (vitalybuka)

<details>
<summary>Changes</summary>

This simplifies handling tags by user code. Now code does not need
to know bit size of tag and its position.


---
Full diff: https://github.com/llvm/llvm-project/pull/75267.diff


6 Files Affected:

- (modified) compiler-rt/include/sanitizer/hwasan_interface.h (+4) 
- (modified) compiler-rt/lib/hwasan/hwasan.cpp (+2) 
- (modified) compiler-rt/lib/hwasan/hwasan.h (+3-3) 
- (modified) compiler-rt/lib/hwasan/hwasan_interface_internal.h (+3) 
- (added) compiler-rt/test/hwasan/TestCases/tag-ptr.cpp (+24) 
- (modified) compiler-rt/test/sanitizer_common/sanitizer_specific.h (+13) 


``````````diff
diff --git a/compiler-rt/include/sanitizer/hwasan_interface.h b/compiler-rt/include/sanitizer/hwasan_interface.h
index abe310c0666948..407f488a24a617 100644
--- a/compiler-rt/include/sanitizer/hwasan_interface.h
+++ b/compiler-rt/include/sanitizer/hwasan_interface.h
@@ -44,6 +44,10 @@ void SANITIZER_CDECL __hwasan_tag_memory(const volatile void *p,
 void *SANITIZER_CDECL __hwasan_tag_pointer(const volatile void *p,
                                            unsigned char tag);
 
+/// Get tag from the pointer.
+unsigned char SANITIZER_CDECL
+__hwasan_get_tag_from_pointer(const volatile void *p);
+
 // Set memory tag from the current SP address to the given address to zero.
 // This is meant to annotate longjmp and other non-local jumps.
 // This function needs to know the (almost) exact destination frame address;
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp
index 2f6cb10caf1be6..52780becbdb264 100644
--- a/compiler-rt/lib/hwasan/hwasan.cpp
+++ b/compiler-rt/lib/hwasan/hwasan.cpp
@@ -678,6 +678,8 @@ uptr __hwasan_tag_pointer(uptr p, u8 tag) {
   return AddTagToPointer(p, tag);
 }
 
+u8 __hwasan_get_tag_from_pointer(uptr p) { return GetTagFromPointer(p); }
+
 void __hwasan_handle_longjmp(const void *sp_dst) {
   uptr dst = (uptr)sp_dst;
   // HWASan does not support tagged SP.
diff --git a/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h
index 37ef4822285110..df21375e81671f 100644
--- a/compiler-rt/lib/hwasan/hwasan.h
+++ b/compiler-rt/lib/hwasan/hwasan.h
@@ -104,9 +104,9 @@ static inline void *UntagPtr(const void *tagged_ptr) {
 }
 
 static inline uptr AddTagToPointer(uptr p, tag_t tag) {
-  return InTaggableRegion(p)
-             ? ((p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift))
-             : p;
+  return InTaggableRegion(p) ? ((p & ~kAddressTagMask) |
+                                ((uptr)(tag & kTagMask) << kAddressTagShift))
+                             : p;
 }
 
 namespace __hwasan {
diff --git a/compiler-rt/lib/hwasan/hwasan_interface_internal.h b/compiler-rt/lib/hwasan/hwasan_interface_internal.h
index e7804cc4903343..8f2f77dad917d2 100644
--- a/compiler-rt/lib/hwasan/hwasan_interface_internal.h
+++ b/compiler-rt/lib/hwasan/hwasan_interface_internal.h
@@ -160,6 +160,9 @@ void __hwasan_tag_memory(uptr p, u8 tag, uptr sz);
 SANITIZER_INTERFACE_ATTRIBUTE
 uptr __hwasan_tag_pointer(uptr p, u8 tag);
 
+SANITIZER_INTERFACE_ATTRIBUTE
+u8 __hwasan_get_tag_from_pointer(uptr p);
+
 SANITIZER_INTERFACE_ATTRIBUTE
 void __hwasan_tag_mismatch(uptr addr, u8 ts);
 
diff --git a/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp b/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp
new file mode 100644
index 00000000000000..2f00e7913bb155
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp
@@ -0,0 +1,24 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <memory>
+#include <sanitizer/hwasan_interface.h>
+#include <set>
+#include <stdio.h>
+
+int main() {
+  auto p = std::make_unique<char>();
+  std::set<void *> ptrs;
+  for (unsigned i = 0;; ++i) {
+    void *ptr = __hwasan_tag_pointer(p.get(), i);
+    if (!ptrs.insert(ptr).second)
+      break;
+    fprintf(stderr, "%p, %u, %u\n", ptr, i, __hwasan_get_tag_from_pointer(ptr));
+    assert(__hwasan_get_tag_from_pointer(ptr) == i);
+  }
+#ifdef __x86_64__
+  assert(ptrs.size() == 8);
+#else
+  assert(ptrs.size() == 256);
+#endif
+}
diff --git a/compiler-rt/test/sanitizer_common/sanitizer_specific.h b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
index 963d91cb305f60..ceb7d72d12dd98 100644
--- a/compiler-rt/test/sanitizer_common/sanitizer_specific.h
+++ b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
@@ -31,6 +31,19 @@ static void make_mem_good(void *p, size_t s) {
 static void make_mem_bad(void *p, size_t s) {
   __asan_poison_memory_region(p, s);
 }
+#elif __has_feature(hwaddress_sanitizer)
+#  include <sanitizer/hwasan_interface.h>
+#  include <stdlib.h>
+static void check_mem_is_good(void *p, size_t s) {
+  if (__hwasan_test_shadow(p, s) != -1)
+    abort();
+}
+static void make_mem_good(void *p, size_t s) {
+  __hwasan_tag_memory(p, __hwasan_get_tag_from_pointer(p), s);
+}
+static void make_mem_bad(void *p, size_t s) {
+  __hwasan_tag_memory(p, ~__hwasan_get_tag_from_pointer(p), s);
+}
 #else
 static void check_mem_is_good(void *p, size_t s) {}
 static void make_mem_good(void *p, size_t s) {}

``````````

</details>


https://github.com/llvm/llvm-project/pull/75267


More information about the llvm-branch-commits mailing list