1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agree to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <sys/stat.h> 19 #include <sys/types.h> 20 #include <unistd.h> 21 22 #include <algorithm> 23 #include <random> 24 #include <string> 25 #include <vector> 26 27 #include <android-base/file.h> 28 #include <android-base/properties.h> 29 #include <android-base/strings.h> 30 #include <gtest/gtest.h> 31 #include <ziparchive/zip_archive.h> 32 #include <ziparchive/zip_writer.h> 33 34 #include "install/install.h" 35 #include "install/wipe_device.h" 36 #include "otautil/paths.h" 37 #include "private/setup_commands.h" 38 #include "recovery_utils/roots.h" 39 BuildZipArchive(const std::map<std::string,std::string> & file_map,int fd,int compression_type)40 static void BuildZipArchive(const std::map<std::string, std::string>& file_map, int fd, 41 int compression_type) { 42 FILE* zip_file = fdopen(fd, "w"); 43 ZipWriter writer(zip_file); 44 for (const auto& [name, content] : file_map) { 45 ASSERT_EQ(0, writer.StartEntry(name.c_str(), compression_type)); 46 ASSERT_EQ(0, writer.WriteBytes(content.data(), content.size())); 47 ASSERT_EQ(0, writer.FinishEntry()); 48 } 49 ASSERT_EQ(0, writer.Finish()); 50 ASSERT_EQ(0, fclose(zip_file)); 51 } 52 TEST(InstallTest,read_metadata_from_package_smoke)53 TEST(InstallTest, read_metadata_from_package_smoke) { 54 TemporaryFile temp_file; 55 const std::string content("abc=defg"); 56 BuildZipArchive({ { "META-INF/com/android/metadata", content } }, temp_file.release(), 57 kCompressStored); 58 59 ZipArchiveHandle zip; 60 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 61 std::map<std::string, std::string> metadata; 62 ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata)); 63 ASSERT_EQ("defg", metadata["abc"]); 64 CloseArchive(zip); 65 66 TemporaryFile temp_file2; 67 BuildZipArchive({ { "META-INF/com/android/metadata", content } }, temp_file2.release(), 68 kCompressDeflated); 69 70 ASSERT_EQ(0, OpenArchive(temp_file2.path, &zip)); 71 metadata.clear(); 72 ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata)); 73 ASSERT_EQ("defg", metadata["abc"]); 74 CloseArchive(zip); 75 } 76 TEST(InstallTest,read_metadata_from_package_no_entry)77 TEST(InstallTest, read_metadata_from_package_no_entry) { 78 TemporaryFile temp_file; 79 BuildZipArchive({ { "fake_entry", "" } }, temp_file.release(), kCompressStored); 80 81 ZipArchiveHandle zip; 82 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 83 std::map<std::string, std::string> metadata; 84 ASSERT_FALSE(ReadMetadataFromPackage(zip, &metadata)); 85 CloseArchive(zip); 86 } 87 TEST(InstallTest,read_wipe_ab_partition_list)88 TEST(InstallTest, read_wipe_ab_partition_list) { 89 std::vector<std::string> partition_list = { 90 "/dev/block/bootdevice/by-name/system_a", "/dev/block/bootdevice/by-name/system_b", 91 "/dev/block/bootdevice/by-name/vendor_a", "/dev/block/bootdevice/by-name/vendor_b", 92 "/dev/block/bootdevice/by-name/userdata", "# Wipe the boot partitions last", 93 "/dev/block/bootdevice/by-name/boot_a", "/dev/block/bootdevice/by-name/boot_b", 94 }; 95 TemporaryFile temp_file; 96 BuildZipArchive({ { "recovery.wipe", android::base::Join(partition_list, '\n') } }, 97 temp_file.release(), kCompressDeflated); 98 std::string wipe_package; 99 ASSERT_TRUE(android::base::ReadFileToString(temp_file.path, &wipe_package)); 100 101 auto package = Package::CreateMemoryPackage( 102 std::vector<uint8_t>(wipe_package.begin(), wipe_package.end()), nullptr); 103 104 auto read_partition_list = GetWipePartitionList(package.get()); 105 std::vector<std::string> expected = { 106 "/dev/block/bootdevice/by-name/system_a", "/dev/block/bootdevice/by-name/system_b", 107 "/dev/block/bootdevice/by-name/vendor_a", "/dev/block/bootdevice/by-name/vendor_b", 108 "/dev/block/bootdevice/by-name/userdata", "/dev/block/bootdevice/by-name/boot_a", 109 "/dev/block/bootdevice/by-name/boot_b", 110 }; 111 ASSERT_EQ(expected, read_partition_list); 112 } 113 TEST(InstallTest,SetUpNonAbUpdateCommands)114 TEST(InstallTest, SetUpNonAbUpdateCommands) { 115 TemporaryFile temp_file; 116 static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary"; 117 BuildZipArchive({ { UPDATE_BINARY_NAME, "" } }, temp_file.release(), kCompressStored); 118 119 ZipArchiveHandle zip; 120 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 121 int status_fd = 10; 122 std::string package = "/path/to/update.zip"; 123 TemporaryDir td; 124 std::string binary_path = std::string(td.path) + "/update_binary"; 125 Paths::Get().set_temporary_update_binary(binary_path); 126 std::vector<std::string> cmd; 127 ASSERT_TRUE(SetUpNonAbUpdateCommands(package, zip, 0, status_fd, &cmd)); 128 ASSERT_EQ(4U, cmd.size()); 129 ASSERT_EQ(binary_path, cmd[0]); 130 ASSERT_EQ("3", cmd[1]); // RECOVERY_API_VERSION 131 ASSERT_EQ(std::to_string(status_fd), cmd[2]); 132 ASSERT_EQ(package, cmd[3]); 133 struct stat sb; 134 ASSERT_EQ(0, stat(binary_path.c_str(), &sb)); 135 ASSERT_EQ(static_cast<mode_t>(0755), sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 136 137 // With non-zero retry count. update_binary will be removed automatically. 138 cmd.clear(); 139 ASSERT_TRUE(SetUpNonAbUpdateCommands(package, zip, 2, status_fd, &cmd)); 140 ASSERT_EQ(5U, cmd.size()); 141 ASSERT_EQ(binary_path, cmd[0]); 142 ASSERT_EQ("3", cmd[1]); // RECOVERY_API_VERSION 143 ASSERT_EQ(std::to_string(status_fd), cmd[2]); 144 ASSERT_EQ(package, cmd[3]); 145 ASSERT_EQ("retry", cmd[4]); 146 sb = {}; 147 ASSERT_EQ(0, stat(binary_path.c_str(), &sb)); 148 ASSERT_EQ(static_cast<mode_t>(0755), sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 149 150 CloseArchive(zip); 151 } 152 TEST(InstallTest,SetUpNonAbUpdateCommands_MissingUpdateBinary)153 TEST(InstallTest, SetUpNonAbUpdateCommands_MissingUpdateBinary) { 154 TemporaryFile temp_file; 155 // The archive must have something to be opened correctly. 156 BuildZipArchive({ { "fake_entry", "" } }, temp_file.release(), kCompressStored); 157 158 // Missing update binary. 159 ZipArchiveHandle zip; 160 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 161 int status_fd = 10; 162 std::string package = "/path/to/update.zip"; 163 TemporaryDir td; 164 Paths::Get().set_temporary_update_binary(std::string(td.path) + "/update_binary"); 165 std::vector<std::string> cmd; 166 ASSERT_FALSE(SetUpNonAbUpdateCommands(package, zip, 0, status_fd, &cmd)); 167 CloseArchive(zip); 168 } 169 VerifyAbUpdateCommands(const std::string & serialno,bool success=true)170 static void VerifyAbUpdateCommands(const std::string& serialno, bool success = true) { 171 TemporaryFile temp_file; 172 173 const std::string properties = "some_properties"; 174 std::string device = android::base::GetProperty("ro.product.device", ""); 175 ASSERT_NE("", device); 176 std::string timestamp = android::base::GetProperty("ro.build.date.utc", ""); 177 ASSERT_NE("", timestamp); 178 179 std::vector<std::string> meta{ "ota-type=AB", "pre-device=" + device, 180 "post-timestamp=" + timestamp }; 181 if (!serialno.empty()) { 182 meta.push_back("serialno=" + serialno); 183 } 184 std::string metadata_string = android::base::Join(meta, "\n"); 185 186 BuildZipArchive({ { "payload.bin", "" }, 187 { "payload_properties.txt", properties }, 188 { "META-INF/com/android/metadata", metadata_string } }, 189 temp_file.release(), kCompressStored); 190 191 ZipArchiveHandle zip; 192 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 193 ZipEntry payload_entry; 194 ASSERT_EQ(0, FindEntry(zip, "payload.bin", &payload_entry)); 195 196 std::map<std::string, std::string> metadata; 197 ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata)); 198 if (success) { 199 ASSERT_TRUE(CheckPackageMetadata(metadata, OtaType::AB)); 200 201 int status_fd = 10; 202 std::string package = "/path/to/update.zip"; 203 std::vector<std::string> cmd; 204 ASSERT_TRUE(SetUpAbUpdateCommands(package, zip, status_fd, &cmd)); 205 ASSERT_EQ(5U, cmd.size()); 206 ASSERT_EQ("/system/bin/update_engine_sideload", cmd[0]); 207 ASSERT_EQ("--payload=file://" + package, cmd[1]); 208 ASSERT_EQ("--offset=" + std::to_string(payload_entry.offset), cmd[2]); 209 ASSERT_EQ("--headers=" + properties, cmd[3]); 210 ASSERT_EQ("--status_fd=" + std::to_string(status_fd), cmd[4]); 211 } else { 212 ASSERT_FALSE(CheckPackageMetadata(metadata, OtaType::AB)); 213 } 214 CloseArchive(zip); 215 } 216 TEST(InstallTest,SetUpAbUpdateCommands)217 TEST(InstallTest, SetUpAbUpdateCommands) { 218 // Empty serialno will pass the verification. 219 VerifyAbUpdateCommands({}); 220 } 221 TEST(InstallTest,SetUpAbUpdateCommands_MissingPayloadPropertiesTxt)222 TEST(InstallTest, SetUpAbUpdateCommands_MissingPayloadPropertiesTxt) { 223 TemporaryFile temp_file; 224 225 std::string device = android::base::GetProperty("ro.product.device", ""); 226 ASSERT_NE("", device); 227 std::string timestamp = android::base::GetProperty("ro.build.date.utc", ""); 228 ASSERT_NE("", timestamp); 229 std::string metadata = android::base::Join( 230 std::vector<std::string>{ 231 "ota-type=AB", "pre-device=" + device, "post-timestamp=" + timestamp, 232 }, 233 "\n"); 234 235 BuildZipArchive( 236 { 237 { "payload.bin", "" }, 238 { "META-INF/com/android/metadata", metadata }, 239 }, 240 temp_file.release(), kCompressStored); 241 242 ZipArchiveHandle zip; 243 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 244 int status_fd = 10; 245 std::string package = "/path/to/update.zip"; 246 std::vector<std::string> cmd; 247 ASSERT_FALSE(SetUpAbUpdateCommands(package, zip, status_fd, &cmd)); 248 CloseArchive(zip); 249 } 250 TEST(InstallTest,SetUpAbUpdateCommands_MultipleSerialnos)251 TEST(InstallTest, SetUpAbUpdateCommands_MultipleSerialnos) { 252 std::string serialno = android::base::GetProperty("ro.serialno", ""); 253 ASSERT_NE("", serialno); 254 255 // Single matching serialno will pass the verification. 256 VerifyAbUpdateCommands(serialno); 257 258 static constexpr char alphabet[] = 259 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 260 auto generator = []() { return alphabet[rand() % (sizeof(alphabet) - 1)]; }; 261 262 // Generate 900 random serial numbers. 263 std::string random_serialno; 264 for (size_t i = 0; i < 900; i++) { 265 generate_n(back_inserter(random_serialno), serialno.size(), generator); 266 random_serialno.append("|"); 267 } 268 // Random serialnos should fail the verification. 269 VerifyAbUpdateCommands(random_serialno, false); 270 271 std::string long_serialno = random_serialno + serialno + "|"; 272 for (size_t i = 0; i < 99; i++) { 273 generate_n(back_inserter(long_serialno), serialno.size(), generator); 274 long_serialno.append("|"); 275 } 276 // String with the matching serialno should pass the verification. 277 VerifyAbUpdateCommands(long_serialno); 278 } 279 TestCheckPackageMetadata(const std::string & metadata_string,OtaType ota_type,bool exptected_result)280 static void TestCheckPackageMetadata(const std::string& metadata_string, OtaType ota_type, 281 bool exptected_result) { 282 TemporaryFile temp_file; 283 BuildZipArchive( 284 { 285 { "META-INF/com/android/metadata", metadata_string }, 286 }, 287 temp_file.release(), kCompressStored); 288 289 ZipArchiveHandle zip; 290 ASSERT_EQ(0, OpenArchive(temp_file.path, &zip)); 291 292 std::map<std::string, std::string> metadata; 293 ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata)); 294 ASSERT_EQ(exptected_result, CheckPackageMetadata(metadata, ota_type)); 295 CloseArchive(zip); 296 } 297 TEST(InstallTest,CheckPackageMetadata_ota_type)298 TEST(InstallTest, CheckPackageMetadata_ota_type) { 299 std::string device = android::base::GetProperty("ro.product.device", ""); 300 ASSERT_NE("", device); 301 302 // ota-type must be present 303 std::string metadata = android::base::Join( 304 std::vector<std::string>{ 305 "pre-device=" + device, 306 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 307 }, 308 "\n"); 309 TestCheckPackageMetadata(metadata, OtaType::AB, false); 310 311 // Checks if ota-type matches 312 metadata = android::base::Join( 313 std::vector<std::string>{ 314 "ota-type=AB", 315 "pre-device=" + device, 316 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 317 }, 318 "\n"); 319 TestCheckPackageMetadata(metadata, OtaType::AB, true); 320 321 TestCheckPackageMetadata(metadata, OtaType::BRICK, false); 322 } 323 TEST(InstallTest,CheckPackageMetadata_device_type)324 TEST(InstallTest, CheckPackageMetadata_device_type) { 325 // device type can not be empty 326 std::string metadata = android::base::Join( 327 std::vector<std::string>{ 328 "ota-type=BRICK", 329 }, 330 "\n"); 331 TestCheckPackageMetadata(metadata, OtaType::BRICK, false); 332 333 // device type mismatches 334 metadata = android::base::Join( 335 std::vector<std::string>{ 336 "ota-type=BRICK", 337 "pre-device=fake_device_type", 338 }, 339 "\n"); 340 TestCheckPackageMetadata(metadata, OtaType::BRICK, false); 341 } 342 TEST(InstallTest,CheckPackageMetadata_serial_number_smoke)343 TEST(InstallTest, CheckPackageMetadata_serial_number_smoke) { 344 std::string device = android::base::GetProperty("ro.product.device", ""); 345 ASSERT_NE("", device); 346 347 // Serial number doesn't need to exist 348 std::string metadata = android::base::Join( 349 std::vector<std::string>{ 350 "ota-type=BRICK", 351 "pre-device=" + device, 352 }, 353 "\n"); 354 TestCheckPackageMetadata(metadata, OtaType::BRICK, true); 355 356 // Serial number mismatches 357 metadata = android::base::Join( 358 std::vector<std::string>{ 359 "ota-type=BRICK", 360 "pre-device=" + device, 361 "serialno=fake_serial", 362 }, 363 "\n"); 364 TestCheckPackageMetadata(metadata, OtaType::BRICK, false); 365 366 std::string serialno = android::base::GetProperty("ro.serialno", ""); 367 ASSERT_NE("", serialno); 368 metadata = android::base::Join( 369 std::vector<std::string>{ 370 "ota-type=BRICK", 371 "pre-device=" + device, 372 "serialno=" + serialno, 373 }, 374 "\n"); 375 TestCheckPackageMetadata(metadata, OtaType::BRICK, true); 376 } 377 TEST(InstallTest,CheckPackageMetadata_multiple_serial_number)378 TEST(InstallTest, CheckPackageMetadata_multiple_serial_number) { 379 std::string device = android::base::GetProperty("ro.product.device", ""); 380 ASSERT_NE("", device); 381 382 std::string serialno = android::base::GetProperty("ro.serialno", ""); 383 ASSERT_NE("", serialno); 384 385 std::vector<std::string> serial_numbers; 386 // Creates a fake serial number string. 387 for (char c = 'a'; c <= 'z'; c++) { 388 serial_numbers.emplace_back(serialno.size(), c); 389 } 390 391 // No matched serialno found. 392 std::string metadata = android::base::Join( 393 std::vector<std::string>{ 394 "ota-type=BRICK", 395 "pre-device=" + device, 396 "serialno=" + android::base::Join(serial_numbers, '|'), 397 }, 398 "\n"); 399 TestCheckPackageMetadata(metadata, OtaType::BRICK, false); 400 401 serial_numbers.emplace_back(serialno); 402 std::shuffle(serial_numbers.begin(), serial_numbers.end(), std::default_random_engine()); 403 metadata = android::base::Join( 404 std::vector<std::string>{ 405 "ota-type=BRICK", 406 "pre-device=" + device, 407 "serialno=" + android::base::Join(serial_numbers, '|'), 408 }, 409 "\n"); 410 TestCheckPackageMetadata(metadata, OtaType::BRICK, true); 411 } 412 TEST(InstallTest,CheckPackageMetadata_ab_build_version)413 TEST(InstallTest, CheckPackageMetadata_ab_build_version) { 414 std::string device = android::base::GetProperty("ro.product.device", ""); 415 ASSERT_NE("", device); 416 417 std::string build_version = android::base::GetProperty("ro.build.version.incremental", ""); 418 ASSERT_NE("", build_version); 419 420 std::string metadata = android::base::Join( 421 std::vector<std::string>{ 422 "ota-type=AB", 423 "pre-device=" + device, 424 "pre-build-incremental=" + build_version, 425 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 426 }, 427 "\n"); 428 TestCheckPackageMetadata(metadata, OtaType::AB, true); 429 430 metadata = android::base::Join( 431 std::vector<std::string>{ 432 "ota-type=AB", 433 "pre-device=" + device, 434 "pre-build-incremental=fake_build", 435 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 436 }, 437 "\n"); 438 TestCheckPackageMetadata(metadata, OtaType::AB, false); 439 } 440 TEST(InstallTest,CheckPackageMetadata_ab_fingerprint)441 TEST(InstallTest, CheckPackageMetadata_ab_fingerprint) { 442 std::string device = android::base::GetProperty("ro.product.device", ""); 443 ASSERT_NE("", device); 444 445 std::string finger_print = android::base::GetProperty("ro.build.fingerprint", ""); 446 ASSERT_NE("", finger_print); 447 448 std::string metadata = android::base::Join( 449 std::vector<std::string>{ 450 "ota-type=AB", 451 "pre-device=" + device, 452 "pre-build=" + finger_print, 453 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 454 }, 455 "\n"); 456 TestCheckPackageMetadata(metadata, OtaType::AB, true); 457 458 metadata = android::base::Join( 459 std::vector<std::string>{ 460 "ota-type=AB", 461 "pre-device=" + device, 462 "pre-build=fake_build_fingerprint", 463 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 464 }, 465 "\n"); 466 TestCheckPackageMetadata(metadata, OtaType::AB, false); 467 } 468 TEST(InstallTest,CheckPackageMetadata_dynamic_fingerprint)469 TEST(InstallTest, CheckPackageMetadata_dynamic_fingerprint) { 470 std::string device = android::base::GetProperty("ro.product.device", ""); 471 ASSERT_FALSE(device.empty()); 472 473 std::string finger_print = android::base::GetProperty("ro.build.fingerprint", ""); 474 ASSERT_FALSE(finger_print.empty()); 475 476 std::string metadata = android::base::Join( 477 std::vector<std::string>{ 478 "ota-type=AB", 479 "pre-device=please|work|" + device + "|please|work", 480 "pre-build=" + finger_print = "pass|this|test", 481 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 482 }, 483 "\n"); 484 TestCheckPackageMetadata(metadata, OtaType::AB, true); 485 486 metadata = android::base::Join( 487 std::vector<std::string>{ 488 "ota-type=AB", 489 "pre-device=" + device, 490 "pre-build=fake_build_fingerprint", 491 "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()), 492 }, 493 "\n"); 494 TestCheckPackageMetadata(metadata, OtaType::AB, false); 495 } 496 TEST(InstallTest,CheckPackageMetadata_ab_post_timestamp)497 TEST(InstallTest, CheckPackageMetadata_ab_post_timestamp) { 498 std::string device = android::base::GetProperty("ro.product.device", ""); 499 ASSERT_NE("", device); 500 501 // post timestamp is required for upgrade. 502 std::string metadata = android::base::Join( 503 std::vector<std::string>{ 504 "ota-type=AB", 505 "pre-device=" + device, 506 }, 507 "\n"); 508 TestCheckPackageMetadata(metadata, OtaType::AB, false); 509 510 // post timestamp should be larger than the timestamp on device. 511 metadata = android::base::Join( 512 std::vector<std::string>{ 513 "ota-type=AB", 514 "pre-device=" + device, 515 "post-timestamp=0", 516 }, 517 "\n"); 518 TestCheckPackageMetadata(metadata, OtaType::AB, false); 519 520 // fingerprint is required for downgrade 521 metadata = android::base::Join( 522 std::vector<std::string>{ 523 "ota-type=AB", 524 "pre-device=" + device, 525 "post-timestamp=0", 526 "ota-downgrade=yes", 527 }, 528 "\n"); 529 TestCheckPackageMetadata(metadata, OtaType::AB, false); 530 531 std::string finger_print = android::base::GetProperty("ro.build.fingerprint", ""); 532 ASSERT_NE("", finger_print); 533 534 metadata = android::base::Join( 535 std::vector<std::string>{ 536 "ota-type=AB", 537 "pre-device=" + device, 538 "post-timestamp=0", 539 "pre-build=" + finger_print, 540 "ota-downgrade=yes", 541 }, 542 "\n"); 543 TestCheckPackageMetadata(metadata, OtaType::AB, true); 544 } 545 TEST(InstallTest,SetupPackageMount_package_path)546 TEST(InstallTest, SetupPackageMount_package_path) { 547 load_volume_table(); 548 bool install_with_fuse; 549 550 // Setup should fail if the input path doesn't exist. 551 ASSERT_FALSE(SetupPackageMount("/does_not_exist", &install_with_fuse)); 552 553 // Package should be installed with fuse if it's not in /cache. 554 TemporaryDir temp_dir; 555 TemporaryFile update_package(temp_dir.path); 556 ASSERT_TRUE(SetupPackageMount(update_package.path, &install_with_fuse)); 557 ASSERT_TRUE(install_with_fuse); 558 559 // Setup should fail if the input path isn't canonicalized. 560 std::string uncanonical_package_path = android::base::Join( 561 std::vector<std::string>{ 562 temp_dir.path, 563 "..", 564 android::base::Basename(temp_dir.path), 565 android::base::Basename(update_package.path), 566 }, 567 '/'); 568 569 ASSERT_EQ(0, access(uncanonical_package_path.c_str(), R_OK)); 570 ASSERT_FALSE(SetupPackageMount(uncanonical_package_path, &install_with_fuse)); 571 } 572