[compiler-rt] [compiler-rt] [Darwin] Strip MTE tags from ASAN and TSAN (PR #166453)
Andrew Haberlandt via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 5 12:04:11 PST 2025
https://github.com/ndrewh updated https://github.com/llvm/llvm-project/pull/166453
>From 8a69c6034444ab8e0b9d3d1a9db1de0d28ce8bff 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 1/2] [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 | 17 ++++++++++++++---
2 files changed, 24 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..ac48392088fb3 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,8 @@ struct MemToShadowImpl {
ALWAYS_INLINE
RawShadow *MemToShadow(uptr x) {
- return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
+ return reinterpret_cast<RawShadow*>(
+ SelectMapping<MemToShadowImpl>(StripTag(x)));
}
struct MemToMetaImpl {
@@ -1011,7 +1022,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>
>From 09d783ec331b15a1d978e361c26a2afbbe4d645c Mon Sep 17 00:00:00 2001
From: Andrew Haberlandt <ahaberlandt at apple.com>
Date: Wed, 5 Nov 2025 12:03:11 -0800
Subject: [PATCH 2/2] STRIP_TAG => STRIP_MTE_TAG, move to common
---
compiler-rt/lib/asan/asan_mapping.h | 13 +++---------
.../lib/sanitizer_common/sanitizer_platform.h | 7 +++++++
compiler-rt/lib/tsan/rtl/tsan_platform.h | 20 +++++++------------
3 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h
index 9fa7f9014445c..338324686a31d 100644
--- a/compiler-rt/lib/asan/asan_mapping.h
+++ b/compiler-rt/lib/asan/asan_mapping.h
@@ -281,18 +281,11 @@ 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) \
- ((STRIP_TAG(mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
+ ((STRIP_MTE_TAG(mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
# define SHADOW_TO_MEM(mem) \
(((mem) - (ASAN_SHADOW_OFFSET)) << (ASAN_SHADOW_SCALE))
@@ -384,7 +377,7 @@ static inline uptr MemToShadowSize(uptr size) {
static inline bool AddrIsInMem(uptr a) {
PROFILE_ASAN_MAPPING();
- a = STRIP_TAG(a);
+ a = STRIP_MTE_TAG(a);
return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a) ||
(flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));
}
@@ -397,7 +390,7 @@ static inline uptr MemToShadow(uptr p) {
static inline bool AddrIsInShadow(uptr a) {
PROFILE_ASAN_MAPPING();
- a = STRIP_TAG(a);
+ a = STRIP_MTE_TAG(a);
return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index 13099fe84b0aa..1b47f3e24d12d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -497,4 +497,11 @@
# endif
#endif
+#if SANITIZER_APPLE && SANITIZER_WORDSIZE == 64
+// MTE uses the lower half of the top byte.
+# define STRIP_MTE_TAG(addr) ((addr) & ~((uptr)0x0f << 56))
+#else
+# define STRIP_MTE_TAG(addr) (addr)
+#endif
+
#endif // SANITIZER_PLATFORM_H
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h
index ac48392088fb3..7089be4d5d7f7 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h
@@ -947,16 +947,6 @@ 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) {
@@ -968,7 +958,9 @@ struct IsAppMemImpl {
};
ALWAYS_INLINE
-bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(StripTag(mem)); }
+bool IsAppMem(uptr mem) {
+ return SelectMapping<IsAppMemImpl>(STRIP_MTE_TAG(mem));
+}
struct IsShadowMemImpl {
template <typename Mapping>
@@ -1008,7 +1000,7 @@ struct MemToShadowImpl {
ALWAYS_INLINE
RawShadow *MemToShadow(uptr x) {
return reinterpret_cast<RawShadow*>(
- SelectMapping<MemToShadowImpl>(StripTag(x)));
+ SelectMapping<MemToShadowImpl>(STRIP_MTE_TAG(x)));
}
struct MemToMetaImpl {
@@ -1022,7 +1014,9 @@ struct MemToMetaImpl {
};
ALWAYS_INLINE
-u32* MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(StripTag(x)); }
+u32* MemToMeta(uptr x) {
+ return SelectMapping<MemToMetaImpl>(STRIP_MTE_TAG(x));
+}
struct ShadowToMemImpl {
template <typename Mapping>
More information about the llvm-commits
mailing list