1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <gtest/gtest.h>
30
31 #if defined(__BIONIC__)
32 #include "gtest_globals.h"
33 #include "utils.h"
34 #endif // defined(__BIONIC__)
35
36 #include <android-base/test_utils.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include <string>
40 #include <tuple>
41
42 #include "platform/bionic/mte.h"
43
44 class MemtagGlobalsTest : public testing::TestWithParam<bool> {};
45
TEST_P(MemtagGlobalsTest,test)46 TEST_P(MemtagGlobalsTest, test) {
47 SKIP_WITH_HWASAN << "MTE globals tests are incompatible with HWASan";
48 #if defined(__BIONIC__) && defined(__aarch64__)
49 SKIP_WITH_NATIVE_BRIDGE; // http://b/242170715
50 std::string binary = GetTestLibRoot() + "/memtag_globals_binary";
51 bool is_static = MemtagGlobalsTest::GetParam();
52 if (is_static) {
53 binary += "_static";
54 }
55
56 chmod(binary.c_str(), 0755);
57 ExecTestHelper eth;
58 eth.SetArgs({binary.c_str(), nullptr});
59 eth.Run(
60 [&]() {
61 execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
62 GTEST_FAIL() << "Failed to execve: " << strerror(errno) << " " << binary.c_str();
63 },
64 // We catch the global-buffer-overflow and crash only when MTE globals is
65 // supported. Note that MTE globals is unsupported for fully static
66 // executables, but we should still make sure the binary passes its
67 // assertions, just that global variables won't be tagged.
68 (mte_supported() && !is_static) ? -SIGSEGV : 0, "Assertions were passed");
69 #else
70 GTEST_SKIP() << "bionic/arm64 only";
71 #endif
72 }
73
74 INSTANTIATE_TEST_SUITE_P(MemtagGlobalsTest, MemtagGlobalsTest, testing::Bool(),
__anon0606e6c80202(const ::testing::TestParamInfo<MemtagGlobalsTest::ParamType>& info) 75 [](const ::testing::TestParamInfo<MemtagGlobalsTest::ParamType>& info) {
76 if (info.param) return "MemtagGlobalsTest_static";
77 return "MemtagGlobalsTest";
78 });
79
TEST(MemtagGlobalsTest,RelrRegressionTestForb314038442)80 TEST(MemtagGlobalsTest, RelrRegressionTestForb314038442) {
81 SKIP_WITH_HWASAN << "MTE globals tests are incompatible with HWASan";
82 #if defined(__BIONIC__) && defined(__aarch64__)
83 std::string binary = GetTestLibRoot() + "/mte_globals_relr_regression_test_b_314038442";
84 chmod(binary.c_str(), 0755);
85 ExecTestHelper eth;
86 eth.SetArgs({binary.c_str(), nullptr});
87 eth.Run(
88 [&]() {
89 execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
90 GTEST_FAIL() << "Failed to execve: " << strerror(errno) << " " << binary.c_str();
91 },
92 /* exit code */ 0, "Program loaded successfully.*Tags are zero!");
93 #else
94 GTEST_SKIP() << "bionic/arm64 only";
95 #endif
96 }
97
TEST(MemtagGlobalsTest,RelrRegressionTestForb314038442WithMteGlobals)98 TEST(MemtagGlobalsTest, RelrRegressionTestForb314038442WithMteGlobals) {
99 if (!mte_supported()) GTEST_SKIP() << "Must have MTE support.";
100 #if defined(__BIONIC__) && defined(__aarch64__)
101 std::string binary = GetTestLibRoot() + "/mte_globals_relr_regression_test_b_314038442_mte";
102 chmod(binary.c_str(), 0755);
103 ExecTestHelper eth;
104 eth.SetArgs({binary.c_str(), nullptr});
105 eth.Run(
106 [&]() {
107 execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
108 GTEST_FAIL() << "Failed to execve: " << strerror(errno) << " " << binary.c_str();
109 },
110 /* exit code */ 0, "Program loaded successfully.*Tags are non-zero");
111 #else
112 GTEST_SKIP() << "bionic/arm64 only";
113 #endif
114 }
115