From 8a69c6034444ab8e0b9d3d1a9db1de0d28ce8bff Mon Sep 17 00:00:00 2001 From: Andrew Haberlandt 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(kMetaShadowBeg); } ALWAYS_INLINE uptr MetaShadowEnd(void) { return SelectMapping(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 static bool Apply(uptr mem) { @@ -958,7 +968,7 @@ struct IsAppMemImpl { }; ALWAYS_INLINE -bool IsAppMem(uptr mem) { return SelectMapping(mem); } +bool IsAppMem(uptr mem) { return SelectMapping(StripTag(mem)); } struct IsShadowMemImpl { template @@ -997,7 +1007,8 @@ struct MemToShadowImpl { ALWAYS_INLINE RawShadow *MemToShadow(uptr x) { - return reinterpret_cast(SelectMapping(x)); + return reinterpret_cast( + SelectMapping(StripTag(x))); } struct MemToMetaImpl { @@ -1011,7 +1022,7 @@ struct MemToMetaImpl { }; ALWAYS_INLINE -u32 *MemToMeta(uptr x) { return SelectMapping(x); } +u32* MemToMeta(uptr x) { return SelectMapping(StripTag(x)); } struct ShadowToMemImpl { template From 09d783ec331b15a1d978e361c26a2afbbe4d645c Mon Sep 17 00:00:00 2001 From: Andrew Haberlandt 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(kMetaShadowBeg); } ALWAYS_INLINE uptr MetaShadowEnd(void) { return SelectMapping(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 static bool Apply(uptr mem) { @@ -968,7 +958,9 @@ struct IsAppMemImpl { }; ALWAYS_INLINE -bool IsAppMem(uptr mem) { return SelectMapping(StripTag(mem)); } +bool IsAppMem(uptr mem) { + return SelectMapping(STRIP_MTE_TAG(mem)); +} struct IsShadowMemImpl { template @@ -1008,7 +1000,7 @@ struct MemToShadowImpl { ALWAYS_INLINE RawShadow *MemToShadow(uptr x) { return reinterpret_cast( - SelectMapping(StripTag(x))); + SelectMapping(STRIP_MTE_TAG(x))); } struct MemToMetaImpl { @@ -1022,7 +1014,9 @@ struct MemToMetaImpl { }; ALWAYS_INLINE -u32* MemToMeta(uptr x) { return SelectMapping(StripTag(x)); } +u32* MemToMeta(uptr x) { + return SelectMapping(STRIP_MTE_TAG(x)); +} struct ShadowToMemImpl { template