blob: e27e58c2276cc4e7257152e5c04da5d7a28e0ee5 [file] [log] [blame]
Tao Bao83b07802017-04-26 14:30:56 -07001/*
2 * Copyright (C) 2017 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
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070017#include <update_verifier/update_verifier.h>
18
Tianjie Xu9eed65e2018-09-14 12:52:02 -070019#include <functional>
Tao Bao83b07802017-04-26 14:30:56 -070020#include <string>
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070021#include <unordered_map>
22#include <vector>
Tao Bao83b07802017-04-26 14:30:56 -070023
24#include <android-base/file.h>
Tao Bao1cc03512018-04-18 17:10:49 -070025#include <android-base/properties.h>
26#include <android-base/strings.h>
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070027#include <google/protobuf/repeated_field.h>
Tao Bao83b07802017-04-26 14:30:56 -070028#include <gtest/gtest.h>
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070029
30#include "care_map.pb.h"
Tao Bao83b07802017-04-26 14:30:56 -070031
Tianjie Xu446b64b2018-09-19 15:45:28 -070032using namespace std::string_literals;
33
Tao Bao83b07802017-04-26 14:30:56 -070034class UpdateVerifierTest : public ::testing::Test {
35 protected:
36 void SetUp() override {
Tao Bao1cc03512018-04-18 17:10:49 -070037 std::string verity_mode = android::base::GetProperty("ro.boot.veritymode", "");
38 verity_supported = android::base::EqualsIgnoreCase(verity_mode, "enforcing");
Tianjie Xu446b64b2018-09-19 15:45:28 -070039
Tianjie Xu9eed65e2018-09-14 12:52:02 -070040 care_map_prefix_ = care_map_dir_.path + "/care_map"s;
Tianjie Xu446b64b2018-09-19 15:45:28 -070041 care_map_pb_ = care_map_dir_.path + "/care_map.pb"s;
42 care_map_txt_ = care_map_dir_.path + "/care_map.txt"s;
Tianjie Xu9eed65e2018-09-14 12:52:02 -070043 // Overrides the the care_map_prefix.
44 verifier_.set_care_map_prefix(care_map_prefix_);
45
46 property_id_ = "ro.build.fingerprint";
47 fingerprint_ = android::base::GetProperty(property_id_, "");
48 // Overrides the property_reader if we cannot read the given property on the device.
49 if (fingerprint_.empty()) {
50 fingerprint_ = "mock_fingerprint";
51 verifier_.set_property_reader([](const std::string& /* id */) { return "mock_fingerprint"; });
52 }
Tianjie Xu446b64b2018-09-19 15:45:28 -070053 }
54
55 void TearDown() override {
56 unlink(care_map_pb_.c_str());
57 unlink(care_map_txt_.c_str());
Tao Bao83b07802017-04-26 14:30:56 -070058 }
59
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070060 // Returns a serialized string of the proto3 message according to the given partition info.
61 std::string ConstructProto(
62 std::vector<std::unordered_map<std::string, std::string>>& partitions) {
Tianjie Xu446b64b2018-09-19 15:45:28 -070063 recovery_update_verifier::CareMap result;
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070064 for (const auto& partition : partitions) {
Tianjie Xu446b64b2018-09-19 15:45:28 -070065 recovery_update_verifier::CareMap::PartitionInfo info;
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070066 if (partition.find("name") != partition.end()) {
67 info.set_name(partition.at("name"));
68 }
69 if (partition.find("ranges") != partition.end()) {
70 info.set_ranges(partition.at("ranges"));
71 }
Tianjie Xu9eed65e2018-09-14 12:52:02 -070072 if (partition.find("id") != partition.end()) {
73 info.set_id(partition.at("id"));
74 }
Tianjie Xu4d9e62d2018-05-11 10:41:44 -070075 if (partition.find("fingerprint") != partition.end()) {
76 info.set_fingerprint(partition.at("fingerprint"));
77 }
78
79 *result.add_partitions() = info;
80 }
81
82 return result.SerializeAsString();
83 }
84
Tao Bao83b07802017-04-26 14:30:56 -070085 bool verity_supported;
Tianjie Xu446b64b2018-09-19 15:45:28 -070086 UpdateVerifier verifier_;
87
88 TemporaryDir care_map_dir_;
Tianjie Xu9eed65e2018-09-14 12:52:02 -070089 std::string care_map_prefix_;
Tianjie Xu446b64b2018-09-19 15:45:28 -070090 std::string care_map_pb_;
91 std::string care_map_txt_;
Tianjie Xu9eed65e2018-09-14 12:52:02 -070092
93 std::string property_id_;
94 std::string fingerprint_;
Tao Bao83b07802017-04-26 14:30:56 -070095};
96
97TEST_F(UpdateVerifierTest, verify_image_no_care_map) {
Tianjie Xu9eed65e2018-09-14 12:52:02 -070098 ASSERT_FALSE(verifier_.ParseCareMap());
Tao Bao83b07802017-04-26 14:30:56 -070099}
100
xunchangaab4b822019-03-13 14:21:48 -0700101TEST_F(UpdateVerifierTest, verify_image_text_format) {
Tao Bao83b07802017-04-26 14:30:56 -0700102 // This test relies on dm-verity support.
103 if (!verity_supported) {
104 GTEST_LOG_(INFO) << "Test skipped on devices without dm-verity support.";
105 return;
106 }
107
Tao Bao83b07802017-04-26 14:30:56 -0700108 std::string content = "system\n2,0,1";
Tianjie Xu446b64b2018-09-19 15:45:28 -0700109 ASSERT_TRUE(android::base::WriteStringToFile(content, care_map_txt_));
xunchangaab4b822019-03-13 14:21:48 -0700110 // CareMap in text format is no longer supported.
111 ASSERT_FALSE(verifier_.ParseCareMap());
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700112}
113
114TEST_F(UpdateVerifierTest, verify_image_empty_care_map) {
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700115 ASSERT_FALSE(verifier_.ParseCareMap());
Tao Bao83b07802017-04-26 14:30:56 -0700116}
117
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700118TEST_F(UpdateVerifierTest, verify_image_protobuf_care_map_smoke) {
119 // This test relies on dm-verity support.
120 if (!verity_supported) {
121 GTEST_LOG_(INFO) << "Test skipped on devices without dm-verity support.";
122 return;
123 }
124
125 std::vector<std::unordered_map<std::string, std::string>> partitions = {
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700126 {
127 { "name", "system" },
128 { "ranges", "2,0,1" },
129 { "id", property_id_ },
130 { "fingerprint", fingerprint_ },
131 },
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700132 };
133
134 std::string proto = ConstructProto(partitions);
Tianjie Xu446b64b2018-09-19 15:45:28 -0700135 ASSERT_TRUE(android::base::WriteStringToFile(proto, care_map_pb_));
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700136 ASSERT_TRUE(verifier_.ParseCareMap());
Tianjie Xu446b64b2018-09-19 15:45:28 -0700137 ASSERT_TRUE(verifier_.VerifyPartitions());
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700138}
139
140TEST_F(UpdateVerifierTest, verify_image_protobuf_care_map_missing_name) {
141 // This test relies on dm-verity support.
142 if (!verity_supported) {
143 GTEST_LOG_(INFO) << "Test skipped on devices without dm-verity support.";
144 return;
145 }
146
147 std::vector<std::unordered_map<std::string, std::string>> partitions = {
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700148 {
149 { "ranges", "2,0,1" },
150 { "id", property_id_ },
151 { "fingerprint", fingerprint_ },
152 },
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700153 };
154
155 std::string proto = ConstructProto(partitions);
Tianjie Xu446b64b2018-09-19 15:45:28 -0700156 ASSERT_TRUE(android::base::WriteStringToFile(proto, care_map_pb_));
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700157 ASSERT_FALSE(verifier_.ParseCareMap());
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700158}
159
160TEST_F(UpdateVerifierTest, verify_image_protobuf_care_map_bad_ranges) {
161 // This test relies on dm-verity support.
162 if (!verity_supported) {
163 GTEST_LOG_(INFO) << "Test skipped on devices without dm-verity support.";
164 return;
165 }
166
167 std::vector<std::unordered_map<std::string, std::string>> partitions = {
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700168 {
169 { "name", "system" },
170 { "ranges", "3,0,1" },
171 { "id", property_id_ },
172 { "fingerprint", fingerprint_ },
173 },
Tianjie Xu4d9e62d2018-05-11 10:41:44 -0700174 };
175
176 std::string proto = ConstructProto(partitions);
Tianjie Xu446b64b2018-09-19 15:45:28 -0700177 ASSERT_TRUE(android::base::WriteStringToFile(proto, care_map_pb_));
Tianjie Xu9eed65e2018-09-14 12:52:02 -0700178 ASSERT_FALSE(verifier_.ParseCareMap());
179}
180
181TEST_F(UpdateVerifierTest, verify_image_protobuf_empty_fingerprint) {
182 // This test relies on dm-verity support.
183 if (!verity_supported) {
184 GTEST_LOG_(INFO) << "Test skipped on devices without dm-verity support.";
185 return;
186 }
187
188 std::vector<std::unordered_map<std::string, std::string>> partitions = {
189 {
190 { "name", "system" },
191 { "ranges", "2,0,1" },
192 },
193 };
194
195 std::string proto = ConstructProto(partitions);
196 ASSERT_TRUE(android::base::WriteStringToFile(proto, care_map_pb_));
197 ASSERT_FALSE(verifier_.ParseCareMap());
198}
199
200TEST_F(UpdateVerifierTest, verify_image_protobuf_fingerprint_mismatch) {
201 // This test relies on dm-verity support.
202 if (!verity_supported) {
203 GTEST_LOG_(INFO) << "Test skipped on devices without dm-verity support.";
204 return;
205 }
206
207 std::vector<std::unordered_map<std::string, std::string>> partitions = {
208 {
209 { "name", "system" },
210 { "ranges", "2,0,1" },
211 { "id", property_id_ },
212 { "fingerprint", "unsupported_fingerprint" },
213 },
214 };
215
216 std::string proto = ConstructProto(partitions);
217 ASSERT_TRUE(android::base::WriteStringToFile(proto, care_map_pb_));
218 ASSERT_FALSE(verifier_.ParseCareMap());
Tao Baoc3196132017-07-24 09:22:39 -0700219}