From 72a91823c18201e30f0235206bdcee617ddfdb2a Mon Sep 17 00:00:00 2001 From: Evgenii Stepanov Date: Mon, 12 Jul 2021 14:44:02 -0700 Subject: [PATCH] Make MTE tests pass with all values of MEMTAG_OPTIONS. Do not assume that tests start with Sync MTE; check the initial setting and change test logic as appropriate. Bug: 192480262 Test: bionic-unit-tests with MEMTAG_OPTIONS=(off|sync|async) Merged-In: Id80301e6426af16f89bd80a7a7ab127b6fd60425 Change-Id: Id80301e6426af16f89bd80a7a7ab127b6fd60425 (cherry picked from commit 53df1f3772ad4843461e78540111b21e9061c051) --- tests/heap_tagging_level_test.cpp | 17 ++++++++--------- tests/mte_test.cpp | 2 +- tests/utils.h | 11 +++++++++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp index b3c8f22a9..5f5904f9a 100644 --- a/tests/heap_tagging_level_test.cpp +++ b/tests/heap_tagging_level_test.cpp @@ -86,16 +86,15 @@ void ExitWithSiCode(int, siginfo_t* info, void*) { TEST(heap_tagging_level, sync_async_bad_accesses_die) { #if defined(__BIONIC__) && defined(__aarch64__) - if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) { - GTEST_SKIP() << "requires MTE support"; + if (!mte_supported() || !running_with_mte()) { + GTEST_SKIP() << "requires MTE to be enabled"; } std::unique_ptr p = std::make_unique(4); - // First, check that memory tagging is enabled and the default tag checking level is sync. - // cc_test targets get sync MTE by default. // We assume that scudo is used on all MTE enabled hardware; scudo inserts a header with a // mismatching tag before each allocation. + EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC)); EXPECT_EXIT( { ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO); @@ -136,7 +135,7 @@ TEST(heap_tagging_level, tagging_level_transitions) { EXPECT_FALSE(SetHeapTaggingLevel(static_cast(12345))); - if (mte_supported()) { + if (mte_supported() && running_with_mte()) { // ASYNC -> ... EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI)); EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC)); @@ -146,14 +145,14 @@ TEST(heap_tagging_level, tagging_level_transitions) { EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI)); EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC)); EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC)); - } else { + } else if (!mte_supported()) { // TBI -> ... EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI)); EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC)); EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC)); } - // TBI -> NONE on non-MTE, ASYNC -> NONE on MTE. + // TBI -> NONE on non-MTE, ASYNC|SYNC|NONE -> NONE on MTE. EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE)); // NONE -> ... @@ -170,8 +169,8 @@ TEST(heap_tagging_level, tagging_level_transition_sync_none) { #if defined(__BIONIC__) && defined(__aarch64__) // We can't test SYNC -> NONE in tagging_level_transitions because we can only make one transition // to NONE (which we use to test ASYNC -> NONE), so we test it here separately. - if (!mte_supported()) { - GTEST_SKIP() << "requires MTE support"; + if (!mte_supported() || !running_with_mte()) { + GTEST_SKIP() << "requires MTE to be enabled"; } EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC)); diff --git a/tests/mte_test.cpp b/tests/mte_test.cpp index f329d8d70..ade95326c 100644 --- a/tests/mte_test.cpp +++ b/tests/mte_test.cpp @@ -38,7 +38,7 @@ static void test_tag_mismatch() { #endif } #if defined(__aarch64__) - if (mte_supported()) { + if (mte_supported() && running_with_mte()) { EXPECT_DEATH( { volatile int load ATTRIBUTE_UNUSED = *mistagged_p; diff --git a/tests/utils.h b/tests/utils.h index 145ba1ac2..592ac0e56 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -304,3 +305,13 @@ template static inline void DoNotOptimize(Tp& value) { asm volatile("" : "+r,m"(value) : : "memory"); } + +static inline bool running_with_mte() { +#ifdef __aarch64__ + int level = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0); + return level >= 0 && (level & PR_TAGGED_ADDR_ENABLE) && + (level & PR_MTE_TCF_MASK) != PR_MTE_TCF_NONE; +#else + return false; +#endif +}