[llvm-branch-commits] [HWASan] [compiler-rt] Add non_negative_pointers option to HWASan alloc (PR #191089)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Apr 8 17:26:13 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Florian Mayer (fmayer)

<details>
<summary>Changes</summary>

This makes sure the allocator does not use the top bit of
the pointer. This is useful when HWASan is used in combination with
signed-integer-overflow detection. Some code uses arithmetic on intptr_t
that overflows for sufficiently large pointers.


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


3 Files Affected:

- (modified) compiler-rt/lib/hwasan/hwasan_allocator.cpp (+6-2) 
- (modified) compiler-rt/lib/hwasan/hwasan_flags.inc (+3) 
- (added) compiler-rt/test/hwasan/TestCases/non_negative_pointers_smoke.c (+21) 


``````````diff
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
index 75dbb336e3445..b238738500b61 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
@@ -153,7 +153,8 @@ void HwasanAllocatorInit() {
       common_flags()->allocator_release_to_os_interval_ms,
       GetAliasRegionStart());
   for (uptr i = 0; i < sizeof(tail_magic); i++)
-    tail_magic[i] = GetCurrentThread()->GenerateRandomTag();
+    tail_magic[i] = GetCurrentThread()->GenerateRandomTag(
+        flags()->non_negative_pointers && kTagBits > 7 ? 7 : kTagBits);
   if (common_flags()->max_allocation_size_mb) {
     max_malloc_size = common_flags()->max_allocation_size_mb << 20;
     max_malloc_size = Min(max_malloc_size, kMaxAllowedMallocSize);
@@ -237,7 +238,10 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
   if (InTaggableRegion(reinterpret_cast<uptr>(user_ptr)) &&
       atomic_load_relaxed(&hwasan_allocator_tagging_enabled) &&
       flags()->tag_in_malloc && malloc_bisect(stack, orig_size)) {
-    tag_t tag = t ? t->GenerateRandomTag() : kFallbackAllocTag;
+    tag_t tag =
+        t ? t->GenerateRandomTag(
+                flags()->non_negative_pointers && kTagBits > 7 ? 7 : kTagBits)
+          : kFallbackAllocTag;
     uptr tag_size = orig_size ? orig_size : 1;
     uptr full_granule_size = RoundDownTo(tag_size, kShadowAlignment);
     user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, full_granule_size, tag);
diff --git a/compiler-rt/lib/hwasan/hwasan_flags.inc b/compiler-rt/lib/hwasan/hwasan_flags.inc
index 058a0457b9e7f..19c654f6d0fb1 100644
--- a/compiler-rt/lib/hwasan/hwasan_flags.inc
+++ b/compiler-rt/lib/hwasan/hwasan_flags.inc
@@ -91,3 +91,6 @@ HWASAN_FLAG(
     "instead of choosing one dynamically."
     "Tip: this can be combined with the compiler option, "
     "-hwasan-mapping-offset, to optimize the instrumentation.")
+
+HWASAN_FLAG(bool, non_negative_pointers, false,
+            "Don't use the top bit of the pointer for tags");
diff --git a/compiler-rt/test/hwasan/TestCases/non_negative_pointers_smoke.c b/compiler-rt/test/hwasan/TestCases/non_negative_pointers_smoke.c
new file mode 100644
index 0000000000000..349c316177798
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/non_negative_pointers_smoke.c
@@ -0,0 +1,21 @@
+// RUN: %clang_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=non_negative_pointers=1 %run %t 2>&1
+
+/// Running this once doesn't really prove anything, but it is a smoke test
+/// that we don't crash.
+
+#include <sanitizer/hwasan_interface.h>
+#include <stdlib.h>
+
+int main() {
+  __hwasan_enable_allocator_tagging();
+  // DUMP: [alloc] {{.*}} 10{{$}}
+  // DUMP: in main{{.*}}malloc_bisect.c
+  char *volatile p = (char *)malloc(10);
+  if (__hwasan_get_tag_from_pointer(p) & (1 << 8))
+    abort();
+  free(p);
+  __hwasan_disable_allocator_tagging();
+
+  return 0;
+}

``````````

</details>


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


More information about the llvm-branch-commits mailing list