diff options
Diffstat (limited to 'standalone/memtag.h')
-rw-r--r-- | standalone/memtag.h | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/standalone/memtag.h b/standalone/memtag.h index 4bdce16faea..c48e228fbe4 100644 --- a/standalone/memtag.h +++ b/standalone/memtag.h @@ -18,7 +18,7 @@ namespace scudo { -#if defined(__aarch64__) || defined(SCUDO_FUZZ) +#if (__clang_major__ >= 12 && defined(__aarch64__)) || defined(SCUDO_FUZZ) // We assume that Top-Byte Ignore is enabled if the architecture supports memory // tagging. Not all operating systems enable TBI, so we only claim architectural @@ -55,7 +55,7 @@ inline uint8_t extractTag(uptr Ptr) { #endif -#if defined(__aarch64__) +#if __clang_major__ >= 12 && defined(__aarch64__) #if SCUDO_LINUX @@ -67,15 +67,27 @@ inline bool systemSupportsMemoryTagging() { } inline bool systemDetectsMemoryTagFaultsTestOnly() { +#ifndef PR_SET_TAGGED_ADDR_CTRL +#define PR_SET_TAGGED_ADDR_CTRL 54 +#endif #ifndef PR_GET_TAGGED_ADDR_CTRL #define PR_GET_TAGGED_ADDR_CTRL 56 #endif +#ifndef PR_TAGGED_ADDR_ENABLE +#define PR_TAGGED_ADDR_ENABLE (1UL << 0) +#endif #ifndef PR_MTE_TCF_SHIFT #define PR_MTE_TCF_SHIFT 1 #endif +#ifndef PR_MTE_TAG_SHIFT +#define PR_MTE_TAG_SHIFT 3 +#endif #ifndef PR_MTE_TCF_NONE #define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) #endif +#ifndef PR_MTE_TCF_SYNC +#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) +#endif #ifndef PR_MTE_TCF_MASK #define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) #endif @@ -84,32 +96,28 @@ inline bool systemDetectsMemoryTagFaultsTestOnly() { PR_MTE_TCF_MASK) != PR_MTE_TCF_NONE; } +inline void enableSystemMemoryTaggingTestOnly() { + prctl(PR_SET_TAGGED_ADDR_CTRL, + PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT), + 0, 0, 0); +} + #else // !SCUDO_LINUX inline bool systemSupportsMemoryTagging() { return false; } -inline bool systemDetectsMemoryTagFaultsTestOnly() { return false; } - -#endif // SCUDO_LINUX - -inline void disableMemoryTagChecksTestOnly() { - __asm__ __volatile__( - R"( - .arch_extension memtag - msr tco, #1 - )"); +inline bool systemDetectsMemoryTagFaultsTestOnly() { + UNREACHABLE("memory tagging not supported"); } -inline void enableMemoryTagChecksTestOnly() { - __asm__ __volatile__( - R"( - .arch_extension memtag - msr tco, #0 - )"); +inline void enableSystemMemoryTaggingTestOnly() { + UNREACHABLE("memory tagging not supported"); } +#endif // SCUDO_LINUX + class ScopedDisableMemoryTagChecks { - size_t PrevTCO; + uptr PrevTCO; public: ScopedDisableMemoryTagChecks() { @@ -134,6 +142,7 @@ public: }; inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) { + ExcludeMask |= 1; // Always exclude Tag 0. uptr TaggedPtr; __asm__ __volatile__( R"( @@ -145,10 +154,14 @@ inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) { return TaggedPtr; } -inline uptr addFixedTag(uptr Ptr, uptr Tag) { return Ptr | (Tag << 56); } +inline uptr addFixedTag(uptr Ptr, uptr Tag) { + DCHECK_LT(Tag, 16); + DCHECK_EQ(untagPointer(Ptr), Ptr); + return Ptr | (Tag << 56); +} inline uptr storeTags(uptr Begin, uptr End) { - DCHECK(Begin % 16 == 0); + DCHECK_EQ(0, Begin % 16); uptr LineSize, Next, Tmp; __asm__ __volatile__( R"( @@ -208,10 +221,12 @@ inline uptr storeTags(uptr Begin, uptr End) { [Tmp] "=&r"(Tmp) : [End] "r"(End) : "memory"); + DCHECK_EQ(0, Begin % 16); return Begin; } inline void storeTag(uptr Ptr) { + DCHECK_EQ(0, Ptr % 16); __asm__ __volatile__(R"( .arch_extension memtag stg %0, [%0] @@ -222,6 +237,7 @@ inline void storeTag(uptr Ptr) { } inline uptr loadTag(uptr Ptr) { + DCHECK_EQ(0, Ptr % 16); uptr TaggedPtr = Ptr; __asm__ __volatile__( R"( @@ -244,11 +260,7 @@ inline bool systemDetectsMemoryTagFaultsTestOnly() { UNREACHABLE("memory tagging not supported"); } -inline void disableMemoryTagChecksTestOnly() { - UNREACHABLE("memory tagging not supported"); -} - -inline void enableMemoryTagChecksTestOnly() { +inline void enableSystemMemoryTaggingTestOnly() { UNREACHABLE("memory tagging not supported"); } @@ -307,7 +319,8 @@ inline void *addFixedTag(void *Ptr, uptr Tag) { template <typename Config> inline constexpr bool allocatorSupportsMemoryTagging() { - return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging; + return archSupportsMemoryTagging() && Config::MaySupportMemoryTagging && + (1 << SCUDO_MIN_ALIGNMENT_LOG) >= archMemoryTagGranuleSize(); } } // namespace scudo |