blob: 47e5b17f4a982d6c612d45035fd2c82e2a1323d1 [file] [log] [blame]
Mårten Kongstad02751232018-04-27 13:16:32 +02001/*
2 * Copyright (C) 2018 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 <cstdio> // fclose
Mårten Kongstad02751232018-04-27 13:16:32 +020018#include <fstream>
19#include <memory>
20#include <sstream>
21#include <string>
Mårten Kongstadce424902019-03-01 08:35:37 +010022#include <utility>
Mårten Kongstad02751232018-04-27 13:16:32 +020023#include <vector>
24
Ryan Mitchell52e1f7a2019-04-12 12:31:42 -070025#include "TestHelpers.h"
Mårten Kongstad02751232018-04-27 13:16:32 +020026#include "android-base/macros.h"
27#include "androidfw/ApkAssets.h"
Ryan Mitchell52e1f7a2019-04-12 12:31:42 -070028#include "gmock/gmock.h"
29#include "gtest/gtest.h"
Mårten Kongstad02751232018-04-27 13:16:32 +020030#include "idmap2/BinaryStreamVisitor.h"
31#include "idmap2/CommandLineOptions.h"
32#include "idmap2/Idmap.h"
33
Mårten Kongstad02751232018-04-27 13:16:32 +020034using ::testing::IsNull;
35using ::testing::NotNull;
36
Mårten Kongstad0eba72a2018-11-29 08:23:14 +010037namespace android::idmap2 {
Mårten Kongstad02751232018-04-27 13:16:32 +020038
39TEST(IdmapTests, TestCanonicalIdmapPathFor) {
40 ASSERT_EQ(Idmap::CanonicalIdmapPathFor("/foo", "/vendor/overlay/bar.apk"),
41 "/foo/vendor@overlay@bar.apk@idmap");
42}
43
44TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
45 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
46 std::istringstream stream(raw);
47 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
48 ASSERT_THAT(header, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +010049 ASSERT_EQ(header->GetMagic(), 0x504d4449U);
50 ASSERT_EQ(header->GetVersion(), 0x01U);
51 ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
52 ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
Mårten Kongstad02751232018-04-27 13:16:32 +020053 ASSERT_EQ(header->GetTargetPath().to_string(), "target.apk");
54 ASSERT_EQ(header->GetOverlayPath().to_string(), "overlay.apk");
55}
56
57TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
58 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
59 // overwrite the target path string, including the terminating null, with '.'
60 for (size_t i = 0x10; i < 0x110; i++) {
61 raw[i] = '.';
62 }
63 std::istringstream stream(raw);
64 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
65 ASSERT_THAT(header, IsNull());
66}
67
68TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
69 const size_t offset = 0x210;
70 std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
71 idmap_raw_data_len - offset);
72 std::istringstream stream(raw);
73
74 std::unique_ptr<const IdmapData::Header> header = IdmapData::Header::FromBinaryStream(stream);
75 ASSERT_THAT(header, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +010076 ASSERT_EQ(header->GetTargetPackageId(), 0x7fU);
77 ASSERT_EQ(header->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +020078}
79
80TEST(IdmapTests, CreateIdmapDataResourceTypeFromBinaryStream) {
81 const size_t offset = 0x214;
82 std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
83 idmap_raw_data_len - offset);
84 std::istringstream stream(raw);
85
86 std::unique_ptr<const IdmapData::TypeEntry> data = IdmapData::TypeEntry::FromBinaryStream(stream);
87 ASSERT_THAT(data, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +010088 ASSERT_EQ(data->GetTargetTypeId(), 0x02U);
89 ASSERT_EQ(data->GetOverlayTypeId(), 0x02U);
90 ASSERT_EQ(data->GetEntryCount(), 1U);
91 ASSERT_EQ(data->GetEntryOffset(), 0U);
92 ASSERT_EQ(data->GetEntry(0), 0U);
Mårten Kongstad02751232018-04-27 13:16:32 +020093}
94
95TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
96 const size_t offset = 0x210;
97 std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
98 idmap_raw_data_len - offset);
99 std::istringstream stream(raw);
100
101 std::unique_ptr<const IdmapData> data = IdmapData::FromBinaryStream(stream);
102 ASSERT_THAT(data, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +0100103 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
104 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200105 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100106 ASSERT_EQ(types.size(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200107
Mårten Kongstadb8779022018-11-29 09:53:17 +0100108 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
109 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x02U);
110 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
111 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
112 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200113
Mårten Kongstadb8779022018-11-29 09:53:17 +0100114 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x03U);
115 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x03U);
116 ASSERT_EQ(types[1]->GetEntryCount(), 3U);
117 ASSERT_EQ(types[1]->GetEntryOffset(), 3U);
118 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200119 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100120 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200121}
122
123TEST(IdmapTests, CreateIdmapFromBinaryStream) {
124 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
125 std::istringstream stream(raw);
126
Mårten Kongstadce424902019-03-01 08:35:37 +0100127 auto result = Idmap::FromBinaryStream(stream);
128 ASSERT_TRUE(result);
129 const auto idmap = std::move(*result);
Mårten Kongstad02751232018-04-27 13:16:32 +0200130
131 ASSERT_THAT(idmap->GetHeader(), NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +0100132 ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
133 ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
134 ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
135 ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200136 ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "target.apk");
137 ASSERT_EQ(idmap->GetHeader()->GetOverlayPath().to_string(), "overlay.apk");
138
139 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100140 ASSERT_EQ(dataBlocks.size(), 1U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200141
142 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
Mårten Kongstadb8779022018-11-29 09:53:17 +0100143 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
144 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200145 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100146 ASSERT_EQ(types.size(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200147
Mårten Kongstadb8779022018-11-29 09:53:17 +0100148 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
149 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x02U);
150 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
151 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
152 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200153
Mårten Kongstadb8779022018-11-29 09:53:17 +0100154 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x03U);
155 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x03U);
156 ASSERT_EQ(types[1]->GetEntryCount(), 3U);
157 ASSERT_EQ(types[1]->GetEntryOffset(), 3U);
158 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200159 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100160 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200161}
162
163TEST(IdmapTests, GracefullyFailToCreateIdmapFromCorruptBinaryStream) {
164 std::string raw(reinterpret_cast<const char*>(idmap_raw_data),
165 10); // data too small
166 std::istringstream stream(raw);
167
Mårten Kongstadce424902019-03-01 08:35:37 +0100168 const auto result = Idmap::FromBinaryStream(stream);
169 ASSERT_FALSE(result);
Mårten Kongstad02751232018-04-27 13:16:32 +0200170}
171
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800172void CreateIdmap(const StringPiece& target_apk_path, const StringPiece& overlay_apk_path,
173 const PolicyBitmask& fulfilled_policies, bool enforce_overlayable,
174 std::unique_ptr<const Idmap>* out_idmap) {
175 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path.to_string());
Mårten Kongstad02751232018-04-27 13:16:32 +0200176 ASSERT_THAT(target_apk, NotNull());
177
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800178 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path.to_string());
Mårten Kongstad02751232018-04-27 13:16:32 +0200179 ASSERT_THAT(overlay_apk, NotNull());
180
Mårten Kongstadce424902019-03-01 08:35:37 +0100181 auto result =
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700182 Idmap::FromApkAssets(*target_apk, *overlay_apk, fulfilled_policies, enforce_overlayable);
Mårten Kongstadce424902019-03-01 08:35:37 +0100183 *out_idmap = result ? std::move(*result) : nullptr;
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800184}
185
186TEST(IdmapTests, CreateIdmapFromApkAssets) {
187 std::unique_ptr<const Idmap> idmap;
188 std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
189 std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk";
190 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC,
191 /* enforce_overlayable */ true, &idmap);
Mårten Kongstad02751232018-04-27 13:16:32 +0200192
193 ASSERT_THAT(idmap->GetHeader(), NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +0100194 ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
195 ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700196 ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x76a20829);
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700197 ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xc054fb26);
Mårten Kongstad02751232018-04-27 13:16:32 +0200198 ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
199 ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
200 ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
201
202 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100203 ASSERT_EQ(dataBlocks.size(), 1U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200204
205 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
206
Mårten Kongstadb8779022018-11-29 09:53:17 +0100207 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
208 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200209
210 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100211 ASSERT_EQ(types.size(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200212
Mårten Kongstadb8779022018-11-29 09:53:17 +0100213 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
214 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
215 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
216 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
217 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200218
Mårten Kongstadb8779022018-11-29 09:53:17 +0100219 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
220 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
221 ASSERT_EQ(types[1]->GetEntryCount(), 4U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700222 ASSERT_EQ(types[1]->GetEntryOffset(), 12U);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100223 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200224 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100225 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
226 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200227}
228
Ryan Mitchell19823452019-01-29 12:01:24 -0800229// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
230TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800231 std::unique_ptr<const Idmap> idmap;
232 std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
233 std::string overlay_apk_path = GetTestDataPath() + "/system-overlay/system-overlay.apk";
234 CreateIdmap(target_apk_path, overlay_apk_path,
235 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
236 /* enforce_overlayable */ true, &idmap);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800237 ASSERT_THAT(idmap, NotNull());
238
239 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
240 ASSERT_EQ(dataBlocks.size(), 1U);
241
242 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
243
244 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
245 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
246
247 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
248 ASSERT_EQ(types.size(), 1U);
249
250 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
251 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800252 ASSERT_EQ(types[0]->GetEntryCount(), 4U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700253 ASSERT_EQ(types[0]->GetEntryOffset(), 8U);
Mårten Kongstad49d835d2019-01-31 10:50:48 +0100254 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_public
255 ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
256 ASSERT_EQ(types[0]->GetEntry(2), 0x0001U); // string/policy_system
257 ASSERT_EQ(types[0]->GetEntry(3), 0x0002U); // string/policy_system_vendor
Winsonb4100202019-02-06 12:05:32 -0800258}
259
260TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800261 std::unique_ptr<const Idmap> idmap;
262 std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
263 std::string overlay_apk_path = GetTestDataPath() + "/signature-overlay/signature-overlay.apk";
264 CreateIdmap(target_apk_path, overlay_apk_path,
265 PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE,
266 /* enforce_overlayable */ true, &idmap);
Winsonb4100202019-02-06 12:05:32 -0800267 ASSERT_THAT(idmap, NotNull());
268
269 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
270 ASSERT_EQ(dataBlocks.size(), 1U);
271
272 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
273
274 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
275 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
276
277 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
278 ASSERT_EQ(types.size(), 1U);
279
280 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
281 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
282 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700283 ASSERT_EQ(types[0]->GetEntryOffset(), 9U);
Mårten Kongstad49d835d2019-01-31 10:50:48 +0100284 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
Winsonb4100202019-02-06 12:05:32 -0800285}
286
Ryan Mitchell19823452019-01-29 12:01:24 -0800287// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
288TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800289 std::unique_ptr<const Idmap> idmap;
290 std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
291 std::string overlay_apk_path =
292 GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk";
293 CreateIdmap(target_apk_path, overlay_apk_path,
294 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
295 /* enforce_overlayable */ true, &idmap);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800296 ASSERT_THAT(idmap, NotNull());
297
298 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
299 ASSERT_EQ(dataBlocks.size(), 1U);
300
301 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
302
303 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
304 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
305
306 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
307 ASSERT_EQ(types.size(), 1U);
308
309 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
310 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800311 ASSERT_EQ(types[0]->GetEntryCount(), 4U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700312 ASSERT_EQ(types[0]->GetEntryOffset(), 8U);
313 ASSERT_EQ(types[0]->GetEntry(0), 0x0005U); // string/policy_public
Mårten Kongstad49d835d2019-01-31 10:50:48 +0100314 ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
Ryan Mitchell939df092019-04-09 17:13:50 -0700315 ASSERT_EQ(types[0]->GetEntry(2), 0x0007U); // string/policy_system
316 ASSERT_EQ(types[0]->GetEntry(3), 0x0008U); // string/policy_system_vendor
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800317}
318
Ryan Mitchell19823452019-01-29 12:01:24 -0800319// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
320TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800321 std::unique_ptr<const Idmap> idmap;
322 std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
323 std::string overlay_apk_path =
324 GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk";
325 CreateIdmap(target_apk_path, overlay_apk_path,
326 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
327 /* enforce_overlayable */ false, &idmap);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800328 ASSERT_THAT(idmap, NotNull());
329
330 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
331 ASSERT_EQ(dataBlocks.size(), 1U);
332
333 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
334
335 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
336 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
337
338 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
339 ASSERT_EQ(types.size(), 1U);
340
341 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
342 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700343 ASSERT_EQ(types[0]->GetEntryCount(), 9U);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800344 ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
345 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
Ryan Mitchell939df092019-04-09 17:13:50 -0700346 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/policy_odm
347 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_oem
348 ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/other
349 ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_product
350 ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_public
351 ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_signature
352 ASSERT_EQ(types[0]->GetEntry(7), 0x0007U); // string/policy_system
353 ASSERT_EQ(types[0]->GetEntry(8), 0x0008U); // string/policy_system_vendor
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800354}
355
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800356// Overlays that do not specify a target <overlayable> can overlay resources defined as overlayable.
Ryan Mitchell19823452019-01-29 12:01:24 -0800357TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800358 std::unique_ptr<const Idmap> idmap;
359 std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk";
360 std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk";
361 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC,
362 /* enforce_overlayable */ false, &idmap);
Ryan Mitchell19823452019-01-29 12:01:24 -0800363 ASSERT_THAT(idmap, NotNull());
364
365 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
366 ASSERT_EQ(dataBlocks.size(), 1U);
367
368 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
369
370 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
371 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
372
373 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
374 ASSERT_EQ(types.size(), 2U);
375
376 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
377 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
378 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
379 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800380 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/int1
Ryan Mitchell19823452019-01-29 12:01:24 -0800381
382 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
383 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
384 ASSERT_EQ(types[1]->GetEntryCount(), 4U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700385 ASSERT_EQ(types[1]->GetEntryOffset(), 12U);
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800386 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); // string/str1
387 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); // string/str2
388 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); // string/str3
389 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U); // string/str4
390}
391
392// Overlays that are not pre-installed and are not signed with the same signature as the target
393// cannot overlay packages that have not defined overlayable resources.
394TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPoliciesPublicFail) {
395 std::unique_ptr<const Idmap> idmap;
396 std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk";
397 std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk";
398 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC,
399 /* enforce_overlayable */ true, &idmap);
400 ASSERT_THAT(idmap, IsNull());
401}
402
403// Overlays that are pre-installed or are signed with the same signature as the target can overlay
404// packages that have not defined overlayable resources.
405TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPolicies) {
406 std::unique_ptr<const Idmap> idmap;
407 std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk";
408 std::string overlay_apk_path =
409 GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk";
410
411 auto CheckEntries = [&]() -> void {
412 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
413 ASSERT_EQ(dataBlocks.size(), 1U);
414
415 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800416 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
417 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
418
419 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
420 ASSERT_EQ(types.size(), 1U);
421
422 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
423 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Ryan Mitchell939df092019-04-09 17:13:50 -0700424 ASSERT_EQ(types[0]->GetEntryCount(), 9U);
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800425 ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
426 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
Ryan Mitchell939df092019-04-09 17:13:50 -0700427 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/policy_odm
428 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_oem
429 ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/other
430 ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_product
431 ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_public
432 ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_signature
433 ASSERT_EQ(types[0]->GetEntry(7), 0x0007U); // string/policy_system
434 ASSERT_EQ(types[0]->GetEntry(8), 0x0008U); // string/policy_system_vendor
Ryan Mitchellb863ca32019-03-07 14:31:54 -0800435 };
436
437 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SIGNATURE,
438 /* enforce_overlayable */ true, &idmap);
439 ASSERT_THAT(idmap, NotNull());
440 CheckEntries();
441
442 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PRODUCT_PARTITION,
443 /* enforce_overlayable */ true, &idmap);
444 ASSERT_THAT(idmap, NotNull());
445 CheckEntries();
446
447 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION,
448 /* enforce_overlayable */ true, &idmap);
449 ASSERT_THAT(idmap, NotNull());
450 CheckEntries();
451
452 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_VENDOR_PARTITION,
453 /* enforce_overlayable */ true, &idmap);
454 ASSERT_THAT(idmap, NotNull());
455 CheckEntries();
Ryan Mitchell939df092019-04-09 17:13:50 -0700456
457 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_ODM_PARTITION,
458 /* enforce_overlayable */ true, &idmap);
459 ASSERT_THAT(idmap, NotNull());
460 CheckEntries();
461
462 CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_OEM_PARTITION,
463 /* enforce_overlayable */ true, &idmap);
464 ASSERT_THAT(idmap, NotNull());
465 CheckEntries();
Ryan Mitchell19823452019-01-29 12:01:24 -0800466}
467
Mårten Kongstad02751232018-04-27 13:16:32 +0200468TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
469 std::string target_apk_path(GetTestDataPath());
470 for (int i = 0; i < 32; i++) {
471 target_apk_path += "/target/../";
472 }
473 target_apk_path += "/target/target.apk";
474 ASSERT_GT(target_apk_path.size(), kIdmapStringLength);
475 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
476 ASSERT_THAT(target_apk, NotNull());
477
478 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
479 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
480 ASSERT_THAT(overlay_apk, NotNull());
481
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700482 const auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC,
483 /* enforce_overlayable */ true);
Mårten Kongstadce424902019-03-01 08:35:37 +0100484 ASSERT_FALSE(result);
Mårten Kongstad02751232018-04-27 13:16:32 +0200485}
486
487TEST(IdmapTests, IdmapHeaderIsUpToDate) {
488 fclose(stderr); // silence expected warnings from libandroidfw
489
490 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
491 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
492 ASSERT_THAT(target_apk, NotNull());
493
494 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
495 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
496 ASSERT_THAT(overlay_apk, NotNull());
497
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700498 auto result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC,
Mårten Kongstadce424902019-03-01 08:35:37 +0100499 /* enforce_overlayable */ true);
500 ASSERT_TRUE(result);
501 const auto idmap = std::move(*result);
Mårten Kongstad02751232018-04-27 13:16:32 +0200502
503 std::stringstream stream;
504 BinaryStreamVisitor visitor(stream);
505 idmap->accept(&visitor);
506
507 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
508 ASSERT_THAT(header, NotNull());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100509 ASSERT_TRUE(header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200510
511 // magic: bytes (0x0, 0x03)
512 std::string bad_magic_string(stream.str());
513 bad_magic_string[0x0] = '.';
514 bad_magic_string[0x1] = '.';
515 bad_magic_string[0x2] = '.';
516 bad_magic_string[0x3] = '.';
517 std::stringstream bad_magic_stream(bad_magic_string);
518 std::unique_ptr<const IdmapHeader> bad_magic_header =
519 IdmapHeader::FromBinaryStream(bad_magic_stream);
520 ASSERT_THAT(bad_magic_header, NotNull());
521 ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100522 ASSERT_FALSE(bad_magic_header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200523
524 // version: bytes (0x4, 0x07)
525 std::string bad_version_string(stream.str());
526 bad_version_string[0x4] = '.';
527 bad_version_string[0x5] = '.';
528 bad_version_string[0x6] = '.';
529 bad_version_string[0x7] = '.';
530 std::stringstream bad_version_stream(bad_version_string);
531 std::unique_ptr<const IdmapHeader> bad_version_header =
532 IdmapHeader::FromBinaryStream(bad_version_stream);
533 ASSERT_THAT(bad_version_header, NotNull());
534 ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100535 ASSERT_FALSE(bad_version_header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200536
537 // target crc: bytes (0x8, 0xb)
538 std::string bad_target_crc_string(stream.str());
539 bad_target_crc_string[0x8] = '.';
540 bad_target_crc_string[0x9] = '.';
541 bad_target_crc_string[0xa] = '.';
542 bad_target_crc_string[0xb] = '.';
543 std::stringstream bad_target_crc_stream(bad_target_crc_string);
544 std::unique_ptr<const IdmapHeader> bad_target_crc_header =
545 IdmapHeader::FromBinaryStream(bad_target_crc_stream);
546 ASSERT_THAT(bad_target_crc_header, NotNull());
547 ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100548 ASSERT_FALSE(bad_target_crc_header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200549
550 // overlay crc: bytes (0xc, 0xf)
551 std::string bad_overlay_crc_string(stream.str());
552 bad_overlay_crc_string[0xc] = '.';
553 bad_overlay_crc_string[0xd] = '.';
554 bad_overlay_crc_string[0xe] = '.';
555 bad_overlay_crc_string[0xf] = '.';
556 std::stringstream bad_overlay_crc_stream(bad_overlay_crc_string);
557 std::unique_ptr<const IdmapHeader> bad_overlay_crc_header =
558 IdmapHeader::FromBinaryStream(bad_overlay_crc_stream);
559 ASSERT_THAT(bad_overlay_crc_header, NotNull());
560 ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100561 ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200562
563 // target path: bytes (0x10, 0x10f)
564 std::string bad_target_path_string(stream.str());
565 bad_target_path_string[0x10] = '\0';
566 std::stringstream bad_target_path_stream(bad_target_path_string);
567 std::unique_ptr<const IdmapHeader> bad_target_path_header =
568 IdmapHeader::FromBinaryStream(bad_target_path_stream);
569 ASSERT_THAT(bad_target_path_header, NotNull());
570 ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100571 ASSERT_FALSE(bad_target_path_header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200572
573 // overlay path: bytes (0x110, 0x20f)
574 std::string bad_overlay_path_string(stream.str());
575 bad_overlay_path_string[0x110] = '\0';
576 std::stringstream bad_overlay_path_stream(bad_overlay_path_string);
577 std::unique_ptr<const IdmapHeader> bad_overlay_path_header =
578 IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
579 ASSERT_THAT(bad_overlay_path_header, NotNull());
580 ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath());
Mårten Kongstad0c6ff1d2019-02-07 02:21:56 +0100581 ASSERT_FALSE(bad_overlay_path_header->IsUpToDate());
Mårten Kongstad02751232018-04-27 13:16:32 +0200582}
583
584class TestVisitor : public Visitor {
585 public:
586 explicit TestVisitor(std::ostream& stream) : stream_(stream) {
587 }
588
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100589 void visit(const Idmap& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200590 stream_ << "TestVisitor::visit(Idmap)" << std::endl;
591 }
592
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100593 void visit(const IdmapHeader& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200594 stream_ << "TestVisitor::visit(IdmapHeader)" << std::endl;
595 }
596
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100597 void visit(const IdmapData& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200598 stream_ << "TestVisitor::visit(IdmapData)" << std::endl;
599 }
600
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100601 void visit(const IdmapData::Header& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200602 stream_ << "TestVisitor::visit(IdmapData::Header)" << std::endl;
603 }
604
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100605 void visit(const IdmapData::TypeEntry& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200606 stream_ << "TestVisitor::visit(IdmapData::TypeEntry)" << std::endl;
607 }
608
609 private:
610 std::ostream& stream_;
611};
612
613TEST(IdmapTests, TestVisitor) {
614 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
615 std::istringstream stream(raw);
616
Mårten Kongstadce424902019-03-01 08:35:37 +0100617 const auto idmap = Idmap::FromBinaryStream(stream);
618 ASSERT_TRUE(idmap);
Mårten Kongstad02751232018-04-27 13:16:32 +0200619
620 std::stringstream test_stream;
621 TestVisitor visitor(test_stream);
Mårten Kongstadce424902019-03-01 08:35:37 +0100622 (*idmap)->accept(&visitor);
Mårten Kongstad02751232018-04-27 13:16:32 +0200623
624 ASSERT_EQ(test_stream.str(),
625 "TestVisitor::visit(Idmap)\n"
626 "TestVisitor::visit(IdmapHeader)\n"
627 "TestVisitor::visit(IdmapData)\n"
628 "TestVisitor::visit(IdmapData::Header)\n"
629 "TestVisitor::visit(IdmapData::TypeEntry)\n"
630 "TestVisitor::visit(IdmapData::TypeEntry)\n");
631}
632
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100633} // namespace android::idmap2