blob: d4463cb365dbf4fbd3c710246d54964d1b5fb885 [file] [log] [blame]
Florian Mayere0e618d2022-09-26 19:30:45 -07001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21
22#include <android-base/file.h>
23#include <android-base/logging.h>
24#include <android-base/properties.h>
25#include <bootloader_message/bootloader_message.h>
Florian Mayer42ab8142023-07-12 18:16:29 -070026#include <string_view>
Florian Mayere0e618d2022-09-26 19:30:45 -070027
28namespace {
29using ::testing::StartsWith;
30
Florian Mayer42ab8142023-07-12 18:16:29 -070031int mtectrl(std::string_view arg) {
Florian Mayere0e618d2022-09-26 19:30:45 -070032 std::string cmd = "mtectrl -t /data/local/tmp/misc_memtag ";
33 cmd += arg;
34 return system(cmd.c_str());
35}
36
Florian Mayer42ab8142023-07-12 18:16:29 -070037int RunMteCtrl() {
38 CHECK(android::base::GetIntProperty("arm64.memtag.test_bootctl_loaded", 0) == 1);
39 std::string arg = android::base::GetProperty("arm64.memtag.test_bootctl", "none");
40 arg += " ";
41 arg += android::base::GetProperty("arm64.memtag.test_bootctl_override", "default");
42 return mtectrl(arg);
43}
44
45void Boot(misc_memtag_message m) {
46 std::string m_str(reinterpret_cast<char*>(&m), sizeof(m));
47 android::base::WriteStringToFile(m_str, "/data/local/tmp/misc_memtag");
48 mtectrl("-s arm64.memtag.test_bootctl -f arm64.memtag.test_bootctl_loaded");
49 // arm64.memtag.test_bootctl got updated, so we trigger ourselves.
50 RunMteCtrl();
51}
52
53void Reboot() {
54 android::base::SetProperty("arm64.memtag.test_bootctl", "INVALID");
55 android::base::SetProperty("arm64.memtag.test_bootctl_loaded", "0");
56 std::string m_str;
57 ASSERT_TRUE(android::base::ReadFileToString("/data/local/tmp/misc_memtag", &m_str));
58 misc_memtag_message m;
59 ASSERT_EQ(m_str.size(), sizeof(m));
60 memcpy(&m, m_str.c_str(), sizeof(m));
61 m.memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG_ONCE;
62 Boot(m);
63}
64
65void SetMemtagProp(const std::string& s) {
66 android::base::SetProperty("arm64.memtag.test_bootctl", s);
67 RunMteCtrl();
68}
69
70void SetOverrideProp(const std::string& s) {
71 android::base::SetProperty("arm64.memtag.test_bootctl_override", s);
72 RunMteCtrl();
73}
74
Florian Mayere0e618d2022-09-26 19:30:45 -070075std::string GetMisc() {
76 std::string data;
77 CHECK(android::base::ReadFileToString("/data/local/tmp/misc_memtag", &data, false));
78 return data;
79}
80
81std::string TestProperty() {
82 return android::base::GetProperty("arm64.memtag.test_bootctl", "");
83}
Florian Mayeredd52142023-06-28 15:19:08 -070084std::string TestFlag() {
85 return android::base::GetProperty("arm64.memtag.test_bootctl_loaded", "");
86}
Florian Mayere0e618d2022-09-26 19:30:45 -070087} // namespace
88
89class MteCtrlTest : public ::testing::Test {
90 void SetUp() override {
91 // Empty fake misc partition.
92 int fd = creat("/data/local/tmp/misc_memtag", 0600);
93 CHECK(fd != -1);
94 CHECK(ftruncate(fd, sizeof(misc_memtag_message)) != -1);
95 close(fd);
96 android::base::SetProperty("arm64.memtag.test_bootctl", "INVALID");
Florian Mayer42ab8142023-07-12 18:16:29 -070097 android::base::SetProperty("arm64.memtag.test_bootctl_override", "");
Florian Mayeredd52142023-06-28 15:19:08 -070098 android::base::SetProperty("arm64.memtag.test_bootctl_loaded", "0");
Florian Mayere0e618d2022-09-26 19:30:45 -070099 }
100 void TearDown() override {
101 CHECK(unlink("/data/local/tmp/misc_memtag") == 0);
102 }
103};
104
105TEST_F(MteCtrlTest, invalid) {
106 EXPECT_NE(mtectrl("memtag-invalid"), 0);
107 EXPECT_NE(mtectrl("memtag override-invalid"), 0);
108}
109
110TEST_F(MteCtrlTest, set_once) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700111 Boot({});
112 SetMemtagProp("memtag-once");
Florian Mayere0e618d2022-09-26 19:30:45 -0700113 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x02"));
114}
115
116TEST_F(MteCtrlTest, set_once_kernel) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700117 Boot({});
118 SetMemtagProp("memtag-once,memtag-kernel");
Florian Mayere0e618d2022-09-26 19:30:45 -0700119 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x06"));
120}
121
Florian Mayere0e618d2022-09-26 19:30:45 -0700122TEST_F(MteCtrlTest, read_memtag) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700123 Boot({});
124 SetMemtagProp("memtag");
125 Reboot();
Florian Mayere0e618d2022-09-26 19:30:45 -0700126 EXPECT_EQ(TestProperty(), "memtag");
Florian Mayeredd52142023-06-28 15:19:08 -0700127 EXPECT_EQ(TestFlag(), "1");
Florian Mayere0e618d2022-09-26 19:30:45 -0700128}
129
Florian Mayer249e5b72022-10-25 17:49:00 -0700130TEST_F(MteCtrlTest, read_invalid_memtag_message) {
131 misc_memtag_message m = {.version = 1, .magic = 0xffff, .memtag_mode = MISC_MEMTAG_MODE_MEMTAG};
Florian Mayer42ab8142023-07-12 18:16:29 -0700132 Boot(m);
Florian Mayeredd52142023-06-28 15:19:08 -0700133 EXPECT_EQ(TestProperty(), "none");
134 EXPECT_EQ(TestFlag(), "1");
Florian Mayer249e5b72022-10-25 17:49:00 -0700135}
136
Florian Mayer234143a2022-10-25 17:53:58 -0700137TEST_F(MteCtrlTest, read_invalid_memtag_mode) {
138 misc_memtag_message m = {.version = MISC_MEMTAG_MESSAGE_VERSION,
139 .magic = MISC_MEMTAG_MAGIC_HEADER,
140 .memtag_mode = MISC_MEMTAG_MODE_MEMTAG | 1u << 31};
Florian Mayer42ab8142023-07-12 18:16:29 -0700141 Boot(m);
Florian Mayer234143a2022-10-25 17:53:58 -0700142 EXPECT_EQ(TestProperty(), "memtag");
Florian Mayeredd52142023-06-28 15:19:08 -0700143 EXPECT_EQ(TestFlag(), "1");
Florian Mayer234143a2022-10-25 17:53:58 -0700144}
145
Florian Mayer42ab8142023-07-12 18:16:29 -0700146TEST_F(MteCtrlTest, set_read_force_off) {
147 Boot({});
148 SetMemtagProp("memtag,memtag-once");
149 SetOverrideProp("force_off");
150 Reboot();
151 EXPECT_EQ(TestProperty(), "memtag-off,forced");
152 SetOverrideProp("default");
153 Reboot();
154 EXPECT_EQ(TestProperty(), "none");
155}
156
157TEST_F(MteCtrlTest, set_read_force_off_already) {
158 Boot({});
159 SetMemtagProp("memtag-off,memtag-once");
160 SetOverrideProp("force_off");
161 Reboot();
162 EXPECT_EQ(TestProperty(), "memtag-off");
163 SetOverrideProp("default");
164 Reboot();
165 EXPECT_EQ(TestProperty(), "memtag-off");
166}
167
168TEST_F(MteCtrlTest, set_read_force_on) {
169 Boot({});
170 SetMemtagProp("memtag-once");
171 SetOverrideProp("force_on");
172 Reboot();
173 EXPECT_EQ(TestProperty(), "memtag,forced");
174 SetOverrideProp("default");
175 Reboot();
176 EXPECT_EQ(TestProperty(), "none");
177}
178
179TEST_F(MteCtrlTest, set_read_force_on_already) {
180 Boot({});
181 SetMemtagProp("memtag,memtag-once");
182 SetOverrideProp("force_on");
183 Reboot();
184 EXPECT_EQ(TestProperty(), "memtag");
185 SetOverrideProp("default");
186 Reboot();
Florian Mayere0e618d2022-09-26 19:30:45 -0700187 EXPECT_EQ(TestProperty(), "memtag");
188}
189
Florian Mayere0e618d2022-09-26 19:30:45 -0700190TEST_F(MteCtrlTest, override) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700191 Boot({});
192 SetMemtagProp(("memtag"));
193 SetMemtagProp(("memtag-once"));
Florian Mayere0e618d2022-09-26 19:30:45 -0700194 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x02"));
195}
196
197TEST_F(MteCtrlTest, read_empty) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700198 Boot({});
Florian Mayeredd52142023-06-28 15:19:08 -0700199 EXPECT_EQ(TestProperty(), "none");
200 EXPECT_EQ(TestFlag(), "1");
Florian Mayere0e618d2022-09-26 19:30:45 -0700201}
202
203TEST_F(MteCtrlTest, force_off_invalid_mode) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700204 Boot({});
205 SetMemtagProp("memtag-invalid");
206 SetOverrideProp("force_off");
207 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x30"));
208 Reboot();
209 EXPECT_EQ(TestProperty(), "memtag-off,forced");
210 SetOverrideProp("default");
211 Reboot();
212 EXPECT_EQ(TestProperty(), "none");
Florian Mayere0e618d2022-09-26 19:30:45 -0700213}
214
215TEST_F(MteCtrlTest, force_on_invalid_mode) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700216 Boot({});
217 SetMemtagProp("memtag-invalid");
218 SetOverrideProp("force_on");
219 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x21"));
220 Reboot();
221 EXPECT_EQ(TestProperty(), "memtag,forced");
222 SetOverrideProp("default");
223 Reboot();
224 EXPECT_EQ(TestProperty(), "none");
Florian Mayere0e618d2022-09-26 19:30:45 -0700225}
226
227TEST_F(MteCtrlTest, mode_invalid_override) {
Florian Mayer42ab8142023-07-12 18:16:29 -0700228 Boot({});
229 SetMemtagProp("memtag");
230 SetOverrideProp("force_invalid");
Florian Mayere0e618d2022-09-26 19:30:45 -0700231 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x01"));
Florian Mayer42ab8142023-07-12 18:16:29 -0700232 Reboot();
233 EXPECT_EQ(TestProperty(), "memtag");
234 SetOverrideProp("default");
235 Reboot();
236 EXPECT_EQ(TestProperty(), "memtag");
Florian Mayere0e618d2022-09-26 19:30:45 -0700237}