From 7ce3ec389b9064231881dff9434ba0087a9e9e27 Mon Sep 17 00:00:00 2001 From: Mitch Phillips Date: Fri, 19 Jan 2024 12:40:25 +0100 Subject: [PATCH] Disable stack protector test with stack MTE Obviously stack MTE conflates with the stack protector test. It doesn't conflate with heap MTE (which we're expecting to push more broadly as part of the -eng build), and so we want to keep this test working under heap-mte scenarios as well. Hence, the check-if-stack-variable-is-tagged test, and only under that case, we skip. Test: atest bionic-unit-tests on a fullmte device (with stack MTE turned back on and the new compiler). Bug: 320448268 Change-Id: I2ecee8a7c46416883235bf5c4ee2de9408047829 --- tests/stack_protector_test.cpp | 43 ++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp index a95e0373c..c4be78c72 100644 --- a/tests/stack_protector_test.cpp +++ b/tests/stack_protector_test.cpp @@ -28,6 +28,7 @@ #include +#include "platform/bionic/mte.h" #include "private/bionic_tls.h" extern "C" pid_t gettid(); // glibc defines this but doesn't declare it anywhere. @@ -100,16 +101,44 @@ TEST(stack_protector, global_guard) { #endif } +// Make sure that a stack variable (`*p`) is tagged under MTE, by forcing the +// stack safety analysis to fail. +int z; +__attribute__((noinline)) void escape_stack_safety_analysis(int* p) { + *p = z; +} + +bool stack_mte_enabled() { + if (!mte_supported()) return false; + int stack_variable; + escape_stack_safety_analysis(&stack_variable); +#if defined(__aarch64__) + return reinterpret_cast(&stack_variable) & (0xfull << 56); +#else // !defined(__aarch64__) + return false; +#endif // defined(__aarch64__) +} + +bool hwasan_enabled() { +#if __has_feature(hwaddress_sanitizer) + return true; +#else + return false; +#endif // __has_feature(hwaddress_sanitizer) +} + using stack_protector_DeathTest = SilentDeathTest; TEST_F(stack_protector_DeathTest, modify_stack_protector) { // In another file to prevent inlining, which removes stack protection. extern void modify_stack_protector_test(); -#if __has_feature(hwaddress_sanitizer) - ASSERT_EXIT(modify_stack_protector_test(), - testing::KilledBySignal(SIGABRT), "tag-mismatch"); -#else - ASSERT_EXIT(modify_stack_protector_test(), - testing::KilledBySignal(SIGABRT), "stack corruption detected"); -#endif + + if (stack_mte_enabled()) { + GTEST_SKIP() << "Stack MTE is enabled, stack protector is not available"; + } else if (hwasan_enabled()) { + ASSERT_EXIT(modify_stack_protector_test(), testing::KilledBySignal(SIGABRT), "tag-mismatch"); + } else { + ASSERT_EXIT(modify_stack_protector_test(), testing::KilledBySignal(SIGABRT), + "stack corruption detected"); + } }