blob: 9e27ccd7cfbb21882f267d393b199e48042fea93 [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);
Ryan Mitchella3628462019-01-14 12:19:40 -0800194 ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xab7cf70d);
Mårten Kongstad02751232018-04-27 13:16:32 +0200195 ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xd470336b);
196 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);
Ryan Mitchella3628462019-01-14 12:19:40 -0800220 ASSERT_EQ(types[1]->GetEntryOffset(), 9U);
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);
257 ASSERT_EQ(types[0]->GetEntryCount(), 3U);
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
260 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/policy_system
261 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_system_vendor
262}
263
Ryan Mitchell19823452019-01-29 12:01:24 -0800264// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
265TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800266 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() +
271 "/system-overlay-invalid/system-overlay-invalid.apk");
272 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
273 ASSERT_THAT(overlay_apk, NotNull());
274
275 std::stringstream error;
276 std::unique_ptr<const Idmap> idmap =
277 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
278 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
279 /* 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);
Ryan Mitchell19823452019-01-29 12:01:24 -0800295 ASSERT_EQ(types[0]->GetEntryCount(), 3U);
296 ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
297 ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public
298 ASSERT_EQ(types[0]->GetEntry(1), 0x0004U); // string/policy_system
299 ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system_vendor
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800300}
301
Ryan Mitchell19823452019-01-29 12:01:24 -0800302// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
303TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800304 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
305 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
306 ASSERT_THAT(target_apk, NotNull());
307
308 const std::string overlay_apk_path(GetTestDataPath() +
309 "/system-overlay-invalid/system-overlay-invalid.apk");
310 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
311 ASSERT_THAT(overlay_apk, NotNull());
312
313 std::stringstream error;
314 std::unique_ptr<const Idmap> idmap =
315 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
316 PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
317 /* enforce_overlayable */ false, error);
318 ASSERT_THAT(idmap, NotNull());
319
320 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
321 ASSERT_EQ(dataBlocks.size(), 1U);
322
323 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
324
325 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
326 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
327
328 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
329 ASSERT_EQ(types.size(), 1U);
330
331 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
332 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
Ryan Mitchella3628462019-01-14 12:19:40 -0800333 ASSERT_EQ(types[0]->GetEntryCount(), 6U);
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800334 ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
335 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
Ryan Mitchella3628462019-01-14 12:19:40 -0800336 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
337 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
338 ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
339 ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system
340 ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800341}
342
Ryan Mitchell19823452019-01-29 12:01:24 -0800343// The resources of APKs that do not include an overlayable declaration should not restrict what
344// resources can be overlaid.
345TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) {
346 const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
347 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
348 ASSERT_THAT(target_apk, NotNull());
349
350 const std::string overlay_apk_path(GetTestDataPath() +
351 "/system-overlay-invalid/system-overlay-invalid.apk");
352 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
353 ASSERT_THAT(overlay_apk, NotNull());
354
355 std::stringstream error;
356 std::unique_ptr<const Idmap> idmap =
357 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
358 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
359 ASSERT_THAT(idmap, NotNull());
360
361 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
362 ASSERT_EQ(dataBlocks.size(), 1U);
363
364 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
365
366 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
367 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
368
369 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
370 ASSERT_EQ(types.size(), 1U);
371
372 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
373 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
374 ASSERT_EQ(types[0]->GetEntryCount(), 6U);
375 ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
376 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
377 ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
378 ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
379 ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
380 ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system
381 ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
382}
383
384// The resources of APKs that do not include an overlayable declaration should not restrict what
385// resources can be overlaid.
386TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
387 const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
388 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
389 ASSERT_THAT(target_apk, NotNull());
390
391 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk");
392 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
393 ASSERT_THAT(overlay_apk, NotNull());
394
395 std::stringstream error;
396 std::unique_ptr<const Idmap> idmap =
397 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
398 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
399 ASSERT_THAT(idmap, NotNull());
400
401 const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
402 ASSERT_EQ(dataBlocks.size(), 1U);
403
404 const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
405
406 ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
407 ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
408
409 const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
410 ASSERT_EQ(types.size(), 2U);
411
412 ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
413 ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
414 ASSERT_EQ(types[0]->GetEntryCount(), 1U);
415 ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
416 ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
417
418 ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
419 ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
420 ASSERT_EQ(types[1]->GetEntryCount(), 4U);
421 ASSERT_EQ(types[1]->GetEntryOffset(), 9U);
422 ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
423 ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
424 ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
425 ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
426}
427
Mårten Kongstad02751232018-04-27 13:16:32 +0200428TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
429 std::string target_apk_path(GetTestDataPath());
430 for (int i = 0; i < 32; i++) {
431 target_apk_path += "/target/../";
432 }
433 target_apk_path += "/target/target.apk";
434 ASSERT_GT(target_apk_path.size(), kIdmapStringLength);
435 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
436 ASSERT_THAT(target_apk, NotNull());
437
438 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
439 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
440 ASSERT_THAT(overlay_apk, NotNull());
441
442 std::stringstream error;
443 std::unique_ptr<const Idmap> idmap =
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800444 Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
445 PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
Mårten Kongstad02751232018-04-27 13:16:32 +0200446 ASSERT_THAT(idmap, IsNull());
447}
448
449TEST(IdmapTests, IdmapHeaderIsUpToDate) {
450 fclose(stderr); // silence expected warnings from libandroidfw
451
452 const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
453 std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
454 ASSERT_THAT(target_apk, NotNull());
455
456 const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
457 std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
458 ASSERT_THAT(overlay_apk, NotNull());
459
460 std::stringstream error;
Mårten Kongstadd10d06d2019-01-07 17:26:25 -0800461 std::unique_ptr<const Idmap> idmap = Idmap::FromApkAssets(
462 target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC,
463 /* enforce_overlayable */ true, error);
Mårten Kongstad02751232018-04-27 13:16:32 +0200464 ASSERT_THAT(idmap, NotNull());
465
466 std::stringstream stream;
467 BinaryStreamVisitor visitor(stream);
468 idmap->accept(&visitor);
469
470 std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
471 ASSERT_THAT(header, NotNull());
472 ASSERT_TRUE(header->IsUpToDate(error)) << error.str();
473
474 // magic: bytes (0x0, 0x03)
475 std::string bad_magic_string(stream.str());
476 bad_magic_string[0x0] = '.';
477 bad_magic_string[0x1] = '.';
478 bad_magic_string[0x2] = '.';
479 bad_magic_string[0x3] = '.';
480 std::stringstream bad_magic_stream(bad_magic_string);
481 std::unique_ptr<const IdmapHeader> bad_magic_header =
482 IdmapHeader::FromBinaryStream(bad_magic_stream);
483 ASSERT_THAT(bad_magic_header, NotNull());
484 ASSERT_NE(header->GetMagic(), bad_magic_header->GetMagic());
485 ASSERT_FALSE(bad_magic_header->IsUpToDate(error));
486
487 // version: bytes (0x4, 0x07)
488 std::string bad_version_string(stream.str());
489 bad_version_string[0x4] = '.';
490 bad_version_string[0x5] = '.';
491 bad_version_string[0x6] = '.';
492 bad_version_string[0x7] = '.';
493 std::stringstream bad_version_stream(bad_version_string);
494 std::unique_ptr<const IdmapHeader> bad_version_header =
495 IdmapHeader::FromBinaryStream(bad_version_stream);
496 ASSERT_THAT(bad_version_header, NotNull());
497 ASSERT_NE(header->GetVersion(), bad_version_header->GetVersion());
498 ASSERT_FALSE(bad_version_header->IsUpToDate(error));
499
500 // target crc: bytes (0x8, 0xb)
501 std::string bad_target_crc_string(stream.str());
502 bad_target_crc_string[0x8] = '.';
503 bad_target_crc_string[0x9] = '.';
504 bad_target_crc_string[0xa] = '.';
505 bad_target_crc_string[0xb] = '.';
506 std::stringstream bad_target_crc_stream(bad_target_crc_string);
507 std::unique_ptr<const IdmapHeader> bad_target_crc_header =
508 IdmapHeader::FromBinaryStream(bad_target_crc_stream);
509 ASSERT_THAT(bad_target_crc_header, NotNull());
510 ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc());
511 ASSERT_FALSE(bad_target_crc_header->IsUpToDate(error));
512
513 // overlay crc: bytes (0xc, 0xf)
514 std::string bad_overlay_crc_string(stream.str());
515 bad_overlay_crc_string[0xc] = '.';
516 bad_overlay_crc_string[0xd] = '.';
517 bad_overlay_crc_string[0xe] = '.';
518 bad_overlay_crc_string[0xf] = '.';
519 std::stringstream bad_overlay_crc_stream(bad_overlay_crc_string);
520 std::unique_ptr<const IdmapHeader> bad_overlay_crc_header =
521 IdmapHeader::FromBinaryStream(bad_overlay_crc_stream);
522 ASSERT_THAT(bad_overlay_crc_header, NotNull());
523 ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc());
524 ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate(error));
525
526 // target path: bytes (0x10, 0x10f)
527 std::string bad_target_path_string(stream.str());
528 bad_target_path_string[0x10] = '\0';
529 std::stringstream bad_target_path_stream(bad_target_path_string);
530 std::unique_ptr<const IdmapHeader> bad_target_path_header =
531 IdmapHeader::FromBinaryStream(bad_target_path_stream);
532 ASSERT_THAT(bad_target_path_header, NotNull());
533 ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath());
534 ASSERT_FALSE(bad_target_path_header->IsUpToDate(error));
535
536 // overlay path: bytes (0x110, 0x20f)
537 std::string bad_overlay_path_string(stream.str());
538 bad_overlay_path_string[0x110] = '\0';
539 std::stringstream bad_overlay_path_stream(bad_overlay_path_string);
540 std::unique_ptr<const IdmapHeader> bad_overlay_path_header =
541 IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
542 ASSERT_THAT(bad_overlay_path_header, NotNull());
543 ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath());
544 ASSERT_FALSE(bad_overlay_path_header->IsUpToDate(error));
545}
546
547class TestVisitor : public Visitor {
548 public:
549 explicit TestVisitor(std::ostream& stream) : stream_(stream) {
550 }
551
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100552 void visit(const Idmap& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200553 stream_ << "TestVisitor::visit(Idmap)" << std::endl;
554 }
555
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100556 void visit(const IdmapHeader& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200557 stream_ << "TestVisitor::visit(IdmapHeader)" << std::endl;
558 }
559
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100560 void visit(const IdmapData& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200561 stream_ << "TestVisitor::visit(IdmapData)" << std::endl;
562 }
563
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100564 void visit(const IdmapData::Header& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200565 stream_ << "TestVisitor::visit(IdmapData::Header)" << std::endl;
566 }
567
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100568 void visit(const IdmapData::TypeEntry& idmap ATTRIBUTE_UNUSED) override {
Mårten Kongstad02751232018-04-27 13:16:32 +0200569 stream_ << "TestVisitor::visit(IdmapData::TypeEntry)" << std::endl;
570 }
571
572 private:
573 std::ostream& stream_;
574};
575
576TEST(IdmapTests, TestVisitor) {
577 std::string raw(reinterpret_cast<const char*>(idmap_raw_data), idmap_raw_data_len);
578 std::istringstream stream(raw);
579
580 std::stringstream error;
581 std::unique_ptr<const Idmap> idmap = Idmap::FromBinaryStream(stream, error);
582 ASSERT_THAT(idmap, NotNull());
583
584 std::stringstream test_stream;
585 TestVisitor visitor(test_stream);
586 idmap->accept(&visitor);
587
588 ASSERT_EQ(test_stream.str(),
589 "TestVisitor::visit(Idmap)\n"
590 "TestVisitor::visit(IdmapHeader)\n"
591 "TestVisitor::visit(IdmapData)\n"
592 "TestVisitor::visit(IdmapData::Header)\n"
593 "TestVisitor::visit(IdmapData::TypeEntry)\n"
594 "TestVisitor::visit(IdmapData::TypeEntry)\n");
595}
596
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100597} // namespace android::idmap2