diff options
author | Evgenii Stepanov <eugenis@google.com> | 2021-01-06 16:03:15 -0800 |
---|---|---|
committer | Evgenii Stepanov <eugenis@google.com> | 2021-01-13 17:18:42 -0800 |
commit | 51741fb38ef27b94245f5f37f798e3f7a05ce01b (patch) | |
tree | 73228166301eeb4d236636cdff45f4accf0d8bbf | |
parent | b4fd07297606de111c10d0f9a000fdb1e2280387 (diff) | |
download | bionic-51741fb38ef27b94245f5f37f798e3f7a05ce01b.tar.gz |
Tests for memory tagging ELF notes.
Bug: b/135772972
Test: bionic-unit-tests
Change-Id: I9b151291d86ef10731eb97db6e68534d5372e06c
-rw-r--r-- | tests/Android.bp | 6 | ||||
-rw-r--r-- | tests/heap_tagging_level_test.cpp | 41 | ||||
-rw-r--r-- | tests/libs/Android.bp | 82 | ||||
-rw-r--r-- | tests/libs/heap_tagging_helper.cpp | 52 |
4 files changed, 177 insertions, 4 deletions
diff --git a/tests/Android.bp b/tests/Android.bp index e7118b3f0..7b5476a5a 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -990,6 +990,12 @@ cc_defaults { "ld_config_test_helper_lib3", "tls_properties_helper", "thread_exit_cb_helper", + "heap_tagging_async_helper", + "heap_tagging_sync_helper", + "heap_tagging_disabled_helper", + "heap_tagging_static_async_helper", + "heap_tagging_static_sync_helper", + "heap_tagging_static_disabled_helper", ], } diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp index 4f8f03649..fd3b7866b 100644 --- a/tests/heap_tagging_level_test.cpp +++ b/tests/heap_tagging_level_test.cpp @@ -18,6 +18,7 @@ #include <sys/prctl.h> #if defined(__BIONIC__) +#include "gtest_globals.h" #include "platform/bionic/malloc.h" #include "platform/bionic/mte.h" #include "utils.h" @@ -90,7 +91,8 @@ TEST(heap_tagging_level, sync_async_bad_accesses_die) { std::unique_ptr<int[]> p = std::make_unique<int[]>(4); - // First, check that memory tagging is enabled and the default tag checking level is async. + // 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_EXIT( @@ -98,15 +100,15 @@ TEST(heap_tagging_level, sync_async_bad_accesses_die) { ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO); p[-1] = 42; }, - testing::ExitedWithCode(SEGV_MTEAERR), ""); + testing::ExitedWithCode(SEGV_MTESERR), ""); - EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC)); + EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC)); EXPECT_EXIT( { ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO); p[-1] = 42; }, - testing::ExitedWithCode(SEGV_MTESERR), ""); + testing::ExitedWithCode(SEGV_MTEAERR), ""); EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE)); volatile int oob ATTRIBUTE_UNUSED = p[-1]; @@ -177,3 +179,34 @@ TEST(heap_tagging_level, tagging_level_transition_sync_none) { GTEST_SKIP() << "bionic/arm64 only"; #endif } + +enum class MemtagNote { NONE, ASYNC, SYNC }; +class MemtagNoteTest : public testing::TestWithParam<std::tuple<MemtagNote, bool>> {}; + +TEST_P(MemtagNoteTest, SEGV) { +#if defined(__BIONIC__) && defined(__aarch64__) + if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) { + GTEST_SKIP() << "requires MTE support"; + } + + const char* kNoteSuffix[] = {"disabled", "async", "sync"}; + const char* kExpectedOutput[] = {"normal exit\n", "SEGV_MTEAERR\n", "SEGV_MTESERR\n"}; + + MemtagNote note = std::get<0>(GetParam()); + bool isStatic = std::get<1>(GetParam()); + std::string helper_base = std::string("heap_tagging_") + (isStatic ? "static_" : "") + + kNoteSuffix[static_cast<int>(note)] + "_helper"; + fprintf(stderr, "=== %s\n", helper_base.c_str()); + std::string helper = GetTestlibRoot() + "/" + helper_base + "/" + helper_base; + chmod(helper.c_str(), 0755); + ExecTestHelper eth; + eth.SetArgs({helper.c_str(), nullptr}); + eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, + kExpectedOutput[static_cast<int>(note)]); +#endif +} + +INSTANTIATE_TEST_SUITE_P(, MemtagNoteTest, + testing::Combine(testing::Values(MemtagNote::NONE, MemtagNote::ASYNC, + MemtagNote::SYNC), + testing::Bool())); diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp index 4b86faf7a..385d1209e 100644 --- a/tests/libs/Android.bp +++ b/tests/libs/Android.bp @@ -1579,3 +1579,85 @@ cc_test_library { defaults: ["bionic_testlib_defaults"], srcs: ["relocations.cpp"], } + +cc_defaults { + name: "bionic_targets_only", + enabled: false, + target: { + android: { + enabled: true, + }, + linux_bionic: { + enabled: true, + }, + }, +} + +cc_test { + name: "heap_tagging_sync_helper", + defaults: ["bionic_testlib_defaults", "bionic_targets_only"], + srcs: ["heap_tagging_helper.cpp"], + sanitize: { + memtag_heap: true, + diag: { + memtag_heap: true, + }, + }, +} + +cc_test { + name: "heap_tagging_async_helper", + defaults: ["bionic_testlib_defaults", "bionic_targets_only"], + srcs: ["heap_tagging_helper.cpp"], + sanitize: { + memtag_heap: true, + diag: { + memtag_heap: false, + }, + }, +} + +cc_test { + name: "heap_tagging_disabled_helper", + defaults: ["bionic_testlib_defaults", "bionic_targets_only"], + srcs: ["heap_tagging_helper.cpp"], + sanitize: { + memtag_heap: false, + }, +} + +cc_test { + name: "heap_tagging_static_sync_helper", + defaults: ["bionic_testlib_defaults", "bionic_targets_only"], + srcs: ["heap_tagging_helper.cpp"], + static_executable: true, + sanitize: { + memtag_heap: true, + diag: { + memtag_heap: true, + }, + }, +} + +cc_test { + name: "heap_tagging_static_async_helper", + defaults: ["bionic_testlib_defaults", "bionic_targets_only"], + srcs: ["heap_tagging_helper.cpp"], + static_executable: true, + sanitize: { + memtag_heap: true, + diag: { + memtag_heap: false, + }, + }, +} + +cc_test { + name: "heap_tagging_static_disabled_helper", + defaults: ["bionic_testlib_defaults", "bionic_targets_only"], + srcs: ["heap_tagging_helper.cpp"], + static_executable: true, + sanitize: { + memtag_heap: false, + }, +} diff --git a/tests/libs/heap_tagging_helper.cpp b/tests/libs/heap_tagging_helper.cpp new file mode 100644 index 000000000..1a970f258 --- /dev/null +++ b/tests/libs/heap_tagging_helper.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <signal.h> +#include <stdio.h> +#include <sys/cdefs.h> +#include <unistd.h> +#include <memory> + +void action(int signo, siginfo_t* info __unused, void*) { +#ifdef __ANDROID__ + if (signo == 11 && info->si_code == SEGV_MTEAERR) { + fprintf(stderr, "SEGV_MTEAERR\n"); + _exit(0); + } + + if (signo == 11 && info->si_code == SEGV_MTESERR) { + fprintf(stderr, "SEGV_MTESERR\n"); + _exit(0); + } +#endif + + fprintf(stderr, "signo %d\n", signo); + _exit(0); +} + +__attribute__((optnone)) int main() { + struct sigaction sa = {}; + sa.sa_sigaction = action; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, nullptr); + + std::unique_ptr<int[]> p = std::make_unique<int[]>(4); + volatile int oob = p[-1]; + (void)oob; + + fprintf(stderr, "normal exit\n"); + return 0; +} |