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