[compiler-rt] [compiler-rt] Strip MTE tags from ASAN and TSAN (PR #166453)

Andrew Haberlandt via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 4 14:02:17 PST 2025


https://github.com/ndrewh created https://github.com/llvm/llvm-project/pull/166453

ASAN and TSAN need to strip tags in order to compute the correct shadow addresses.

>From d6f2291943017a8e9d08fc3bcac46eaef0799aa8 Mon Sep 17 00:00:00 2001
From: Andrew Haberlandt <ahaberlandt at apple.com>
Date: Tue, 4 Nov 2025 13:59:03 -0800
Subject: [PATCH] [compiler-rt] Strip MTE tags from ASAN and TSAN

ASAN and TSAN need to strip tags in order to compute the correct shadow
addresses.
---
 compiler-rt/lib/asan/asan_mapping.h      | 11 ++++++++++-
 compiler-rt/lib/tsan/rtl/tsan_platform.h | 16 +++++++++++++---
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h
index bddae9a074056..9fa7f9014445c 100644
--- a/compiler-rt/lib/asan/asan_mapping.h
+++ b/compiler-rt/lib/asan/asan_mapping.h
@@ -281,11 +281,18 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.
 
 }  // namespace __asan
 
+#  if SANITIZER_APPLE && SANITIZER_WORDSIZE == 64
+#    define TAG_MASK ((uptr)0x0f << 56)  // Lower half of top byte
+#    define STRIP_TAG(addr) ((addr) & ~TAG_MASK)
+#  else
+#    define STRIP_TAG(addr) (addr)
+#  endif
+
 #  if defined(__sparc__) && SANITIZER_WORDSIZE == 64
 #    include "asan_mapping_sparc64.h"
 #  else
 #    define MEM_TO_SHADOW(mem) \
-      (((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
+      ((STRIP_TAG(mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
 #    define SHADOW_TO_MEM(mem) \
       (((mem) - (ASAN_SHADOW_OFFSET)) << (ASAN_SHADOW_SCALE))
 
@@ -377,6 +384,7 @@ static inline uptr MemToShadowSize(uptr size) {
 
 static inline bool AddrIsInMem(uptr a) {
   PROFILE_ASAN_MAPPING();
+  a = STRIP_TAG(a);
   return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a) ||
          (flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));
 }
@@ -389,6 +397,7 @@ static inline uptr MemToShadow(uptr p) {
 
 static inline bool AddrIsInShadow(uptr a) {
   PROFILE_ASAN_MAPPING();
+  a = STRIP_TAG(a);
   return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
 }
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h
index 00b493bf2d931..fc7d1be61ca4c 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h
@@ -947,6 +947,16 @@ uptr MetaShadowBeg(void) { return SelectMapping<MappingField>(kMetaShadowBeg); }
 ALWAYS_INLINE
 uptr MetaShadowEnd(void) { return SelectMapping<MappingField>(kMetaShadowEnd); }
 
+ALWAYS_INLINE
+uptr StripTag(uptr addr) {
+#if SANITIZER_APPLE
+  constexpr uptr kTagMask = ((uptr)0x0f << 56);  // Lower half of top byte
+  return addr & ~kTagMask;
+#else
+  return addr;
+#endif
+}
+
 struct IsAppMemImpl {
   template <typename Mapping>
   static bool Apply(uptr mem) {
@@ -958,7 +968,7 @@ struct IsAppMemImpl {
 };
 
 ALWAYS_INLINE
-bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
+bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(StripTag(mem)); }
 
 struct IsShadowMemImpl {
   template <typename Mapping>
@@ -997,7 +1007,7 @@ struct MemToShadowImpl {
 
 ALWAYS_INLINE
 RawShadow *MemToShadow(uptr x) {
-  return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
+  return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(StripTag(mem)));
 }
 
 struct MemToMetaImpl {
@@ -1011,7 +1021,7 @@ struct MemToMetaImpl {
 };
 
 ALWAYS_INLINE
-u32 *MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(x); }
+u32 *MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(StripTag(x)); }
 
 struct ShadowToMemImpl {
   template <typename Mapping>



More information about the llvm-commits mailing list