blob: 5fe77f872e03c2cf73baa110172c93418ea2ff09 [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>
26
27namespace {
28using ::testing::StartsWith;
29
30int mtectrl(const char* arg) {
31 std::string cmd = "mtectrl -t /data/local/tmp/misc_memtag ";
32 cmd += arg;
33 return system(cmd.c_str());
34}
35
36std::string GetMisc() {
37 std::string data;
38 CHECK(android::base::ReadFileToString("/data/local/tmp/misc_memtag", &data, false));
39 return data;
40}
41
42std::string TestProperty() {
43 return android::base::GetProperty("arm64.memtag.test_bootctl", "");
44}
45} // namespace
46
47class MteCtrlTest : public ::testing::Test {
48 void SetUp() override {
49 // Empty fake misc partition.
50 int fd = creat("/data/local/tmp/misc_memtag", 0600);
51 CHECK(fd != -1);
52 CHECK(ftruncate(fd, sizeof(misc_memtag_message)) != -1);
53 close(fd);
54 android::base::SetProperty("arm64.memtag.test_bootctl", "INVALID");
55 }
56 void TearDown() override {
57 CHECK(unlink("/data/local/tmp/misc_memtag") == 0);
58 }
59};
60
61TEST_F(MteCtrlTest, invalid) {
62 EXPECT_NE(mtectrl("memtag-invalid"), 0);
63 EXPECT_NE(mtectrl("memtag override-invalid"), 0);
64}
65
66TEST_F(MteCtrlTest, set_once) {
67 ASSERT_EQ(mtectrl("memtag-once"), 0);
68 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x02"));
69}
70
71TEST_F(MteCtrlTest, set_once_kernel) {
72 ASSERT_EQ(mtectrl("memtag-once,memtag-kernel"), 0);
73 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x06"));
74}
75
76TEST_F(MteCtrlTest, set_memtag) {
77 ASSERT_EQ(mtectrl("memtag"), 0);
78 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x01"));
79}
80
81TEST_F(MteCtrlTest, set_memtag_force_off) {
82 ASSERT_EQ(mtectrl("memtag force_off"), 0);
83 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x10"));
84}
85
86TEST_F(MteCtrlTest, read_memtag) {
87 ASSERT_EQ(mtectrl("memtag"), 0);
88 ASSERT_EQ(mtectrl("-s arm64.memtag.test_bootctl"), 0);
89 EXPECT_EQ(TestProperty(), "memtag");
90}
91
Florian Mayer249e5b72022-10-25 17:49:00 -070092TEST_F(MteCtrlTest, read_invalid_memtag_message) {
93 misc_memtag_message m = {.version = 1, .magic = 0xffff, .memtag_mode = MISC_MEMTAG_MODE_MEMTAG};
94 std::string m_str(reinterpret_cast<char*>(&m), sizeof(m));
95 android::base::WriteStringToFile(m_str, "/data/local/tmp/misc_memtag");
96 ASSERT_EQ(mtectrl("-s arm64.memtag.test_bootctl"), 0);
97 EXPECT_EQ(TestProperty(), "");
98}
99
Florian Mayer234143a2022-10-25 17:53:58 -0700100TEST_F(MteCtrlTest, read_invalid_memtag_mode) {
101 misc_memtag_message m = {.version = MISC_MEMTAG_MESSAGE_VERSION,
102 .magic = MISC_MEMTAG_MAGIC_HEADER,
103 .memtag_mode = MISC_MEMTAG_MODE_MEMTAG | 1u << 31};
104 std::string m_str(reinterpret_cast<char*>(&m), sizeof(m));
105 android::base::WriteStringToFile(m_str, "/data/local/tmp/misc_memtag");
106 ASSERT_NE(mtectrl("-s arm64.memtag.test_bootctl"), 0);
107 EXPECT_EQ(TestProperty(), "memtag");
108}
109
Florian Mayere0e618d2022-09-26 19:30:45 -0700110TEST_F(MteCtrlTest, set_read_memtag) {
111 ASSERT_EQ(mtectrl("-s arm64.memtag.test_bootctl memtag"), 0);
112 EXPECT_EQ(TestProperty(), "memtag");
113}
114
115TEST_F(MteCtrlTest, set_read_force_off) {
116 ASSERT_EQ(mtectrl("-s arm64.memtag.test_bootctl memtag,memtag-once force_off"), 0);
117 EXPECT_EQ(TestProperty(), "memtag-once,memtag-off");
118}
119
120TEST_F(MteCtrlTest, override) {
121 ASSERT_EQ(mtectrl("memtag"), 0);
122 ASSERT_EQ(mtectrl("memtag-once"), 0);
123 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x02"));
124}
125
126TEST_F(MteCtrlTest, read_empty) {
127 ASSERT_EQ(mtectrl("-s arm64.memtag.test_bootctl"), 0);
128 EXPECT_EQ(TestProperty(), "");
129}
130
131TEST_F(MteCtrlTest, force_off_invalid_mode) {
132 mtectrl("-s arm64.memtag.test_bootctl memtag-invalid force_off");
133 EXPECT_EQ(TestProperty(), "memtag-off");
134 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x10"));
135}
136
137TEST_F(MteCtrlTest, force_on_invalid_mode) {
138 mtectrl("-s arm64.memtag.test_bootctl memtag-invalid force_on");
139 EXPECT_EQ(TestProperty(), "memtag");
140 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x01"));
141}
142
143TEST_F(MteCtrlTest, mode_invalid_override) {
144 mtectrl("-s arm64.memtag.test_bootctl memtag force_invalid");
145 EXPECT_EQ(TestProperty(), "memtag");
146 EXPECT_THAT(GetMisc(), StartsWith("\x01\x5a\xfe\xfe\x5a\x01"));
147}