blob: 53ec03ba3d5e1932aa03296a854c7706dcf125d9 [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
18
19#include <fstream>
20#include <memory>
21#include <sstream>
22#include <string>
23#include <vector>
24
25#include "gmock/gmock.h"
26#include "gtest/gtest.h"
27
28#include "android-base/macros.h"
29#include "androidfw/ApkAssets.h"
30
31#include "idmap2/BinaryStreamVisitor.h"
32#include "idmap2/CommandLineOptions.h"
33#include "idmap2/Idmap.h"
34
35#include "TestHelpers.h"
36
37using ::testing::IsNull;
38using ::testing::NotNull;
39
Mårten Kongstad0eba72a2018-11-29 08:23:14 +010040namespace android::idmap2 {
Mårten Kongstad02751232018-04-27 13:16:32 +020041
42TEST(IdmapTests, TestCanonicalIdmapPathFor) {
43 ASSERT_EQ(Idmap::CanonicalIdmapPathFor("/foo", "/vendor/overlay/bar.apk"),
44 "/foo/vendor@overlay@bar.apk@idmap");
45}
46
47TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
48 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
49 std::istringstream stream(raw);
50 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
51 ASSERT_THAT(header, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +010052 ASSERT_EQ(header->GetMagic(), 0x504d4449U);
53 ASSERT_EQ(header->GetVersion(), 0x01U);
54 ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
55 ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
Mårten Kongstad02751232018-04-27 13:16:32 +020056 ASSERT_EQ(header->GetTargetPath().to_string(), "target.apk");
57 ASSERT_EQ(header->GetOverlayPath().to_string(), "overlay.apk");
58}
59
60TEST(IdmapTests, FailToCreateIdmapHeaderFromBinaryStreamIfPathTooLong) {
61 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
62 // overwrite the target path string, including the terminating null, with '.'
63 for (size_t i = 0x10; i < 0x110; i++) {
64 raw[i] = '.';
65 }
66 std::istringstream stream(raw);
67 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
68 ASSERT_THAT(header, IsNull());
69}
70
71TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
72 const size_t offset = 0x210;
73 std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
74 idmap_raw_data_len - offset);
75 std::istringstream stream(raw);
76
77 std::unique_ptr<const IdmapData::Header> header = IdmapData::Header::FromBinaryStream(stream);
78 ASSERT_THAT(header, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +010079 ASSERT_EQ(header->GetTargetPackageId(), 0x7fU);
80 ASSERT_EQ(header->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +020081}
82
83TEST(IdmapTests, CreateIdmapDataResourceTypeFromBinaryStream) {
84 const size_t offset = 0x214;
85 std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
86 idmap_raw_data_len - offset);
87 std::istringstream stream(raw);
88
89 std::unique_ptr<const IdmapData::TypeEntry> data = IdmapData::TypeEntry::FromBinaryStream(stream);
90 ASSERT_THAT(data, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +010091 ASSERT_EQ(data->GetTargetTypeId(), 0x02U);
92 ASSERT_EQ(data->GetOverlayTypeId(), 0x02U);
93 ASSERT_EQ(data->GetEntryCount(), 1U);
94 ASSERT_EQ(data->GetEntryOffset(), 0U);
95 ASSERT_EQ(data->GetEntry(0), 0U);
Mårten Kongstad02751232018-04-27 13:16:32 +020096}
97
98TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
99 const size_t offset = 0x210;
100 std::string raw(reinterpret_cast<const char*>(idmap_raw_data + offset),
101 idmap_raw_data_len - offset);
102 std::istringstream stream(raw);
103
104 std::unique_ptr<const IdmapData> data = IdmapData::FromBinaryStream(stream);
105 ASSERT_THAT(data, NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +0100106 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
107 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200108 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100109 ASSERT_EQ(types.size(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200110
Mårten Kongstadb8779022018-11-29 09:53:17 +0100111 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
112 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x02U);
113 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
114 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
115 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200116
Mårten Kongstadb8779022018-11-29 09:53:17 +0100117 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x03U);
118 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x03U);
119 ASSERT_EQ(types[1]->GetEntryCount(), 3U);
120 ASSERT_EQ(types[1]->GetEntryOffset(), 3U);
121 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200122 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100123 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200124}
125
126TEST(IdmapTests, CreateIdmapFromBinaryStream) {
127 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
128 std::istringstream stream(raw);
129
130 std::stringstream error;
131 std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(stream, error);
132 ASSERT_THAT(idmap, NotNull());
133
134 ASSERT_THAT(idmap->GetHeader(), NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +0100135 ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
136 ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
137 ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
138 ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200139 ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), "target.apk");
140 ASSERT_EQ(idmap->GetHeader()->GetOverlayPath().to_string(), "overlay.apk");
141
142 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100143 ASSERT_EQ(dataBlocks.size(), 1U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200144
145 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
Mårten Kongstadb8779022018-11-29 09:53:17 +0100146 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
147 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200148 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100149 ASSERT_EQ(types.size(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200150
Mårten Kongstadb8779022018-11-29 09:53:17 +0100151 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
152 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x02U);
153 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
154 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
155 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200156
Mårten Kongstadb8779022018-11-29 09:53:17 +0100157 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x03U);
158 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x03U);
159 ASSERT_EQ(types[1]->GetEntryCount(), 3U);
160 ASSERT_EQ(types[1]->GetEntryOffset(), 3U);
161 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200162 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100163 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200164}
165
166TEST(IdmapTests, GracefullyFailToCreateIdmapFromCorruptBinaryStream) {
167 std::string raw(reinterpret_cast<const char*>(idmap_raw_data),
168 10); // data too small
169 std::istringstream stream(raw);
170
171 std::stringstream error;
172 std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(stream, error);
173 ASSERT_THAT(idmap, IsNull());
174}
175
176TEST(IdmapTests, CreateIdmapFromApkAssets) {
177 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
178 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
179 ASSERT_THAT(target_apk, NotNull());
180
181 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
182 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
183 ASSERT_THAT(overlay_apk, NotNull());
184
185 std::stringstream error;
186 std::unique_ptr<const Idmap> idmap =
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800187 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
188 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
Mårten Kongstad02751232018-04-27 13:16:32 +0200189 ASSERT_THAT(idmap, NotNull());
190
191 ASSERT_THAT(idmap->GetHeader(), NotNull());
Mårten Kongstadb8779022018-11-29 09:53:17 +0100192 ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
193 ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800194 ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xd513ca1b);
195 ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x8635c2ed);
Mårten Kongstad02751232018-04-27 13:16:32 +0200196 ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
197 ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
198 ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
199
200 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100201 ASSERT_EQ(dataBlocks.size(), 1U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200202
203 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
204
Mårten Kongstadb8779022018-11-29 09:53:17 +0100205 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
206 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200207
208 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
Mårten Kongstadb8779022018-11-29 09:53:17 +0100209 ASSERT_EQ(types.size(), 2U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200210
Mårten Kongstadb8779022018-11-29 09:53:17 +0100211 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
212 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
213 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
214 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
215 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200216
Mårten Kongstadb8779022018-11-29 09:53:17 +0100217 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
218 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
219 ASSERT_EQ(types[1]->GetEntryCount(), 4U);
Winsonb4100202019-02-06 12:05:32 -0800220 ASSERT_EQ(types[1]->GetEntryOffset(), 10U);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100221 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200222 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
Mårten Kongstadb8779022018-11-29 09:53:17 +0100223 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
224 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
Mårten Kongstad02751232018-04-27 13:16:32 +0200225}
226
Ryan Mitchell19823452019-01-29 12:01:24 -0800227// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
228TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800229 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
230 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
231 ASSERT_THAT(target_apk, NotNull());
232
233 const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay/system-overlay.apk");
234 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
235 ASSERT_THAT(overlay_apk, NotNull());
236
237 std::stringstream error;
238 std::unique_ptr<const Idmap> idmap =
239 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
240 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
241 /* enforce_overlayable */ true, error);
242 ASSERT_THAT(idmap, NotNull());
243
244 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
245 ASSERT_EQ(dataBlocks.size(), 1U);
246
247 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
248
249 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
250 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
251
252 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
253 ASSERT_EQ(types.size(), 1U);
254
255 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
256 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800257 ASSERT_EQ(types[0]->GetEntryCount(), 4U);
Ryan Mitchella3628462019-01-14 12:19:40 -0800258 ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800259 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_public
Winsonb4100202019-02-06 12:05:32 -0800260 ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
261 ASSERT_EQ(types[0]->GetEntry(2), 0x0001U); // string/policy_system
262 ASSERT_EQ(types[0]->GetEntry(3), 0x0002U); // string/policy_system_vendor
263}
264
265TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
266 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
267 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
268 ASSERT_THAT(target_apk, NotNull());
269
270 const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk");
271 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
272 ASSERT_THAT(overlay_apk, NotNull());
273
274 uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE;
275
276 std::stringstream error;
277 std::unique_ptr<const Idmap> idmap =
278 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
279 policy_flags, /* enforce_overlayable */ true, error);
280 ASSERT_THAT(idmap, NotNull());
281
282 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
283 ASSERT_EQ(dataBlocks.size(), 1U);
284
285 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
286
287 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
288 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
289
290 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
291 ASSERT_EQ(types.size(), 1U);
292
293 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
294 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
295 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
296 ASSERT_EQ(types[0]->GetEntryOffset(), 7U);
297 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
298}
299
300TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) {
301 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
302 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
303 ASSERT_THAT(target_apk, NotNull());
304
305 const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk");
306 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
307 ASSERT_THAT(overlay_apk, NotNull());
308
309 uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC;
310
311 std::stringstream error;
312 std::unique_ptr<const Idmap> idmap =
313 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
314 policy_flags, /* enforce_overlayable */ true, error);
315 ASSERT_THAT(idmap, NotNull());
316
317 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
318 ASSERT_EQ(dataBlocks.size(), 1U);
319
320 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
321
322 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
323 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 0U);
324
325 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
326 ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800327}
328
Ryan Mitchell19823452019-01-29 12:01:24 -0800329// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
330TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800331 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
332 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
333 ASSERT_THAT(target_apk, NotNull());
334
335 const std::string overlay_apk_path(GetTestDataPath() +
336 "/system-overlay-invalid/system-overlay-invalid.apk");
337 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
338 ASSERT_THAT(overlay_apk, NotNull());
339
340 std::stringstream error;
341 std::unique_ptr<const Idmap> idmap =
342 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
343 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
344 /* enforce_overlayable */ true, error);
345 ASSERT_THAT(idmap, NotNull());
346
347 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
348 ASSERT_EQ(dataBlocks.size(), 1U);
349
350 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
351
352 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
353 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
354
355 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
356 ASSERT_EQ(types.size(), 1U);
357
358 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
359 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800360 ASSERT_EQ(types[0]->GetEntryCount(), 4U);
Ryan Mitchell19823452019-01-29 12:01:24 -0800361 ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
362 ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public
Winsonb4100202019-02-06 12:05:32 -0800363 ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
364 ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system
365 ASSERT_EQ(types[0]->GetEntry(3), 0x0006U); // string/policy_system_vendor
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800366}
367
Ryan Mitchell19823452019-01-29 12:01:24 -0800368// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
369TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800370 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
371 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
372 ASSERT_THAT(target_apk, NotNull());
373
374 const std::string overlay_apk_path(GetTestDataPath() +
375 "/system-overlay-invalid/system-overlay-invalid.apk");
376 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
377 ASSERT_THAT(overlay_apk, NotNull());
378
379 std::stringstream error;
380 std::unique_ptr<const Idmap> idmap =
381 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
382 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
383 /* enforce_overlayable */ false, error);
384 ASSERT_THAT(idmap, NotNull());
385
386 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
387 ASSERT_EQ(dataBlocks.size(), 1U);
388
389 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
390
391 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
392 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
393
394 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
395 ASSERT_EQ(types.size(), 1U);
396
397 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
398 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800399 ASSERT_EQ(types[0]->GetEntryCount(), 7U);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800400 ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
401 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
Ryan Mitchella3628462019-01-14 12:19:40 -0800402 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
403 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
Winsonb4100202019-02-06 12:05:32 -0800404 ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_signature
405 ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_public
406 ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system
407 ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800408}
409
Ryan Mitchell19823452019-01-29 12:01:24 -0800410// The resources of APKs that do not include an overlayable declaration should not restrict what
411// resources can be overlaid.
412TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) {
413 const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
414 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
415 ASSERT_THAT(target_apk, NotNull());
416
417 const std::string overlay_apk_path(GetTestDataPath() +
418 "/system-overlay-invalid/system-overlay-invalid.apk");
419 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
420 ASSERT_THAT(overlay_apk, NotNull());
421
422 std::stringstream error;
423 std::unique_ptr<const Idmap> idmap =
424 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
425 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
426 ASSERT_THAT(idmap, NotNull());
427
428 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
429 ASSERT_EQ(dataBlocks.size(), 1U);
430
431 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
432
433 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
434 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
435
436 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
437 ASSERT_EQ(types.size(), 1U);
438
439 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
440 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Winsonb4100202019-02-06 12:05:32 -0800441 ASSERT_EQ(types[0]->GetEntryCount(), 7U);
Ryan Mitchell19823452019-01-29 12:01:24 -0800442 ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
443 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
444 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
445 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
446 ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
Winsonb4100202019-02-06 12:05:32 -0800447 ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/string/policy_signature
448 ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system
449 ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor
Ryan Mitchell19823452019-01-29 12:01:24 -0800450}
451
452// The resources of APKs that do not include an overlayable declaration should not restrict what
453// resources can be overlaid.
454TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
455 const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
456 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
457 ASSERT_THAT(target_apk, NotNull());
458
459 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk");
460 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
461 ASSERT_THAT(overlay_apk, NotNull());
462
463 std::stringstream error;
464 std::unique_ptr<const Idmap> idmap =
465 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
466 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
467 ASSERT_THAT(idmap, NotNull());
468
469 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
470 ASSERT_EQ(dataBlocks.size(), 1U);
471
472 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
473
474 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
475 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
476
477 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
478 ASSERT_EQ(types.size(), 2U);
479
480 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
481 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
482 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
483 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
484 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
485
486 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
487 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
488 ASSERT_EQ(types[1]->GetEntryCount(), 4U);
Winsonb4100202019-02-06 12:05:32 -0800489 ASSERT_EQ(types[1]->GetEntryOffset(), 10U);
Ryan Mitchell19823452019-01-29 12:01:24 -0800490 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
491 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
492 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
493 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
494}
495
Mårten Kongstad02751232018-04-27 13:16:32 +0200496TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
497 std::string target_apk_path(GetTestDataPath());
498 for (int i = 0; i < 32; i++) {
499 target_apk_path += "/target/../";
500 }
501 target_apk_path += "/target/target.apk";
502 ASSERT_GT(target_apk_path.size(), kIdmapStringLength);
503 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
504 ASSERT_THAT(target_apk, NotNull());
505
506 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
507 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
508 ASSERT_THAT(overlay_apk, NotNull());
509
510 std::stringstream error;
511 std::unique_ptr<const Idmap> idmap =
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800512 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
513 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
Mårten Kongstad02751232018-04-27 13:16:32 +0200514 ASSERT_THAT(idmap, IsNull());
515}
516
517TEST(IdmapTests, IdmapHeaderIsUpToDate) {
518 fclose(stderr); // silence expected warnings from libandroidfw
519
520 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
521 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
522 ASSERT_THAT(target_apk, NotNull());
523
524 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
525 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
526 ASSERT_THAT(overlay_apk, NotNull());
527
528 std::stringstream error;
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800529 std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(
530 target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC,
531 /* enforce_overlayable */ true, error);
Mårten Kongstad02751232018-04-27 13:16:32 +0200532 ASSERT_THAT(idmap, NotNull());
533
534 std::stringstream stream;
535 BinaryStreamVisitor visitor(stream);
536 idmap->accept(&visitor);
537
538 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
539 ASSERT_THAT(header, NotNull());
540 ASSERT_TRUE(header->IsUpToDate(error)) << error.str();
541
542 // magic: bytes (0x0, 0x03)
543 std::string bad_magic_string(stream.str());
544 bad_magic_string[0x0] = '.';
545 bad_magic_string[0x1] = '.';
546 bad_magic_string[0x2] = '.';
547 bad_magic_string[0x3] = '.';
548 std::stringstream bad_magic_stream(bad_magic_string);
549 std::unique_ptr<const IdmapHeader> bad_magic_header =
550 IdmapHeader::FromBinaryStream(bad_magic_stream);
551 ASSERT_THAT(bad_magic_header, NotNull());
552 ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic());
553 ASSERT_FALSE(bad_magic_header->IsUpToDate(error));
554
555 // version: bytes (0x4, 0x07)
556 std::string bad_version_string(stream.str());
557 bad_version_string[0x4] = '.';
558 bad_version_string[0x5] = '.';
559 bad_version_string[0x6] = '.';
560 bad_version_string[0x7] = '.';
561 std::stringstream bad_version_stream(bad_version_string);
562 std::unique_ptr<const IdmapHeader> bad_version_header =
563 IdmapHeader::FromBinaryStream(bad_version_stream);
564 ASSERT_THAT(bad_version_header, NotNull());
565 ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion());
566 ASSERT_FALSE(bad_version_header->IsUpToDate(error));
567
568 // target crc: bytes (0x8, 0xb)
569 std::string bad_target_crc_string(stream.str());
570 bad_target_crc_string[0x8] = '.';
571 bad_target_crc_string[0x9] = '.';
572 bad_target_crc_string[0xa] = '.';
573 bad_target_crc_string[0xb] = '.';
574 std::stringstream bad_target_crc_stream(bad_target_crc_string);
575 std::unique_ptr<const IdmapHeader> bad_target_crc_header =
576 IdmapHeader::FromBinaryStream(bad_target_crc_stream);
577 ASSERT_THAT(bad_target_crc_header, NotNull());
578 ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc());
579 ASSERT_FALSE(bad_target_crc_header->IsUpToDate(error));
580
581 // overlay crc: bytes (0xc, 0xf)
582 std::string bad_overlay_crc_string(stream.str());
583 bad_overlay_crc_string[0xc] = '.';
584 bad_overlay_crc_string[0xd] = '.';
585 bad_overlay_crc_string[0xe] = '.';
586 bad_overlay_crc_string[0xf] = '.';
587 std::stringstream bad_overlay_crc_stream(bad_overlay_crc_string);
588 std::unique_ptr<const IdmapHeader> bad_overlay_crc_header =
589 IdmapHeader::FromBinaryStream(bad_overlay_crc_stream);
590 ASSERT_THAT(bad_overlay_crc_header, NotNull());
591 ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc());
592 ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate(error));
593
594 // target path: bytes (0x10, 0x10f)
595 std::string bad_target_path_string(stream.str());
596 bad_target_path_string[0x10] = '\0';
597 std::stringstream bad_target_path_stream(bad_target_path_string);
598 std::unique_ptr<const IdmapHeader> bad_target_path_header =
599 IdmapHeader::FromBinaryStream(bad_target_path_stream);
600 ASSERT_THAT(bad_target_path_header, NotNull());
601 ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath());
602 ASSERT_FALSE(bad_target_path_header->IsUpToDate(error));
603
604 // overlay path: bytes (0x110, 0x20f)
605 std::string bad_overlay_path_string(stream.str());
606 bad_overlay_path_string[0x110] = '\0';
607 std::stringstream bad_overlay_path_stream(bad_overlay_path_string);
608 std::unique_ptr<const IdmapHeader> bad_overlay_path_header =
609 IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
610 ASSERT_THAT(bad_overlay_path_header, NotNull());
611 ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath());
612 ASSERT_FALSE(bad_overlay_path_header->IsUpToDate(error));
613}
614
615class TestVisitor : public Visitor {
616 public:
617 explicit TestVisitor(std::ostream& stream) : stream_(stream) {
618 }
619
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100620 void visit(const Idmap& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200621 stream_ << "TestVisitor::visit(Idmap)" << std::endl;
622 }
623
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100624 void visit(const IdmapHeader& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200625 stream_ << "TestVisitor::visit(IdmapHeader)" << std::endl;
626 }
627
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100628 void visit(const IdmapData& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200629 stream_ << "TestVisitor::visit(IdmapData)" << std::endl;
630 }
631
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100632 void visit(const IdmapData::Header& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200633 stream_ << "TestVisitor::visit(IdmapData::Header)" << std::endl;
634 }
635
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100636 void visit(const IdmapData::TypeEntry& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200637 stream_ << "TestVisitor::visit(IdmapData::TypeEntry)" << std::endl;
638 }
639
640 private:
641 std::ostream& stream_;
642};
643
644TEST(IdmapTests, TestVisitor) {
645 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
646 std::istringstream stream(raw);
647
648 std::stringstream error;
649 std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(stream, error);
650 ASSERT_THAT(idmap, NotNull());
651
652 std::stringstream test_stream;
653 TestVisitor visitor(test_stream);
654 idmap->accept(&visitor);
655
656 ASSERT_EQ(test_stream.str(),
657 "TestVisitor::visit(Idmap)\n"
658 "TestVisitor::visit(IdmapHeader)\n"
659 "TestVisitor::visit(IdmapData)\n"
660 "TestVisitor::visit(IdmapData::Header)\n"
661 "TestVisitor::visit(IdmapData::TypeEntry)\n"
662 "TestVisitor::visit(IdmapData::TypeEntry)\n");
663}
664
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100665} // namespace android::idmap2