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