1 /*
2  * Copyright (C) 2007 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 "install/install.h"
18 
19 #include <ctype.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <inttypes.h>
23 #include <limits.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/wait.h>
27 #include <unistd.h>
28 
29 #include <algorithm>
30 #include <atomic>
31 #include <chrono>
32 #include <condition_variable>
33 #include <filesystem>
34 #include <functional>
35 #include <limits>
36 #include <mutex>
37 #include <thread>
38 #include <vector>
39 
40 #include <android-base/file.h>
41 #include <android-base/logging.h>
42 #include <android-base/parsedouble.h>
43 #include <android-base/parseint.h>
44 #include <android-base/properties.h>
45 #include <android-base/stringprintf.h>
46 #include <android-base/strings.h>
47 #include <android-base/unique_fd.h>
48 
49 #include "install/spl_check.h"
50 #include "install/wipe_data.h"
51 #include "install/wipe_device.h"
52 #include "otautil/error_code.h"
53 #include "otautil/package.h"
54 #include "otautil/paths.h"
55 #include "otautil/sysutil.h"
56 #include "otautil/verifier.h"
57 #include "private/setup_commands.h"
58 #include "recovery_ui/ui.h"
59 #include "recovery_utils/roots.h"
60 #include "recovery_utils/thermalutil.h"
61 
62 using namespace std::chrono_literals;
63 
64 static constexpr int kRecoveryApiVersion = 3;
65 // We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed
66 // into target_files.zip. Assert the version defined in code and in Android.mk are consistent.
67 static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions.");
68 
69 // Default allocation of progress bar segments to operations
70 static constexpr int VERIFICATION_PROGRESS_TIME = 60;
71 static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
72 // The charater used to separate dynamic fingerprints. e.x. sargo|aosp-sargo
73 static const char* FINGERPRING_SEPARATOR = "|";
74 static constexpr auto&& RELEASE_KEYS_TAG = "release-keys";
75 // If brick packages are smaller than |MEMORY_PACKAGE_LIMIT|, read the entire package into memory
76 static constexpr size_t MEMORY_PACKAGE_LIMIT = 1024 * 1024;
77 
78 static std::condition_variable finish_log_temperature;
79 static bool isInStringList(const std::string& target_token, const std::string& str_list,
80                            const std::string& deliminator);
81 
ReadMetadataFromPackage(ZipArchiveHandle zip,std::map<std::string,std::string> * metadata)82 bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::string>* metadata) {
83   CHECK(metadata != nullptr);
84 
85   static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
86   ZipEntry64 entry;
87   if (FindEntry(zip, METADATA_PATH, &entry) != 0) {
88     LOG(ERROR) << "Failed to find " << METADATA_PATH;
89     return false;
90   }
91 
92   uint32_t length = entry.uncompressed_length;
93   std::string metadata_string(length, '\0');
94   int32_t err =
95       ExtractToMemory(zip, &entry, reinterpret_cast<uint8_t*>(&metadata_string[0]), length);
96   if (err != 0) {
97     LOG(ERROR) << "Failed to extract " << METADATA_PATH << ": " << ErrorCodeString(err);
98     return false;
99   }
100 
101   for (const std::string& line : android::base::Split(metadata_string, "\n")) {
102     size_t eq = line.find('=');
103     if (eq != std::string::npos) {
104       metadata->emplace(android::base::Trim(line.substr(0, eq)),
105                         android::base::Trim(line.substr(eq + 1)));
106     }
107   }
108 
109   return true;
110 }
111 
112 // Gets the value for the given key in |metadata|. Returns an emtpy string if the key isn't
113 // present.
get_value(const std::map<std::string,std::string> & metadata,const std::string & key)114 static std::string get_value(const std::map<std::string, std::string>& metadata,
115                              const std::string& key) {
116   const auto& it = metadata.find(key);
117   return (it == metadata.end()) ? "" : it->second;
118 }
119 
OtaTypeToString(OtaType type)120 static std::string OtaTypeToString(OtaType type) {
121   switch (type) {
122     case OtaType::AB:
123       return "AB";
124     case OtaType::BLOCK:
125       return "BLOCK";
126     case OtaType::BRICK:
127       return "BRICK";
128   }
129 }
130 
131 // Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
ReadSourceTargetBuild(const std::map<std::string,std::string> & metadata,std::vector<std::string> * log_buffer)132 static void ReadSourceTargetBuild(const std::map<std::string, std::string>& metadata,
133                                   std::vector<std::string>* log_buffer) {
134   // Examples of the pre-build and post-build strings in metadata:
135   //   pre-build-incremental=2943039
136   //   post-build-incremental=2951741
137   auto source_build = get_value(metadata, "pre-build-incremental");
138   if (!source_build.empty()) {
139     log_buffer->push_back("source_build: " + source_build);
140   }
141 
142   auto target_build = get_value(metadata, "post-build-incremental");
143   if (!target_build.empty()) {
144     log_buffer->push_back("target_build: " + target_build);
145   }
146 }
147 
148 // Checks the build version, fingerprint and timestamp in the metadata of the A/B package.
149 // Downgrading is not allowed unless explicitly enabled in the package and only for
150 // incremental packages.
CheckAbSpecificMetadata(const std::map<std::string,std::string> & metadata)151 static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& metadata) {
152   // Incremental updates should match the current build.
153   auto device_pre_build = android::base::GetProperty("ro.build.version.incremental", "");
154   auto pkg_pre_build = get_value(metadata, "pre-build-incremental");
155   if (!pkg_pre_build.empty() && pkg_pre_build != device_pre_build) {
156     LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected "
157                << device_pre_build;
158     return false;
159   }
160 
161   auto device_fingerprint = android::base::GetProperty("ro.build.fingerprint", "");
162   auto pkg_pre_build_fingerprint = get_value(metadata, "pre-build");
163   if (!pkg_pre_build_fingerprint.empty() &&
164       !isInStringList(device_fingerprint, pkg_pre_build_fingerprint, FINGERPRING_SEPARATOR)) {
165     LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected "
166                << device_fingerprint;
167     return false;
168   }
169 
170   // Check for downgrade version.
171   int64_t build_timestamp =
172       android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
173   int64_t pkg_post_timestamp = 0;
174   // We allow to full update to the same version we are running, in case there
175   // is a problem with the current copy of that version.
176   auto pkg_post_timestamp_string = get_value(metadata, "post-timestamp");
177   if (pkg_post_timestamp_string.empty() ||
178       !android::base::ParseInt(pkg_post_timestamp_string, &pkg_post_timestamp) ||
179       pkg_post_timestamp < build_timestamp) {
180     if (get_value(metadata, "ota-downgrade") != "yes") {
181       LOG(ERROR) << "Update package is older than the current build, expected a build "
182                     "newer than timestamp "
183                  << build_timestamp << " but package has timestamp " << pkg_post_timestamp
184                  << " and downgrade not allowed.";
185       return false;
186     }
187     if (pkg_pre_build_fingerprint.empty()) {
188       LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
189       return false;
190     }
191   }
192   const auto post_build = get_value(metadata, "post-build");
193   const auto build_fingerprint = android::base::Tokenize(post_build, "/");
194   if (!build_fingerprint.empty()) {
195     const auto& post_build_tag = build_fingerprint.back();
196     const auto build_tag = android::base::GetProperty("ro.build.tags", "");
197     if (build_tag != post_build_tag) {
198       LOG(ERROR) << "Post build-tag " << post_build_tag << " does not match device build tag "
199                  << build_tag;
200       return false;
201     }
202   }
203 
204   return true;
205 }
206 
CheckPackageMetadata(const std::map<std::string,std::string> & metadata,OtaType ota_type)207 bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type) {
208   auto package_ota_type = get_value(metadata, "ota-type");
209   auto expected_ota_type = OtaTypeToString(ota_type);
210   if (ota_type != OtaType::AB && ota_type != OtaType::BRICK) {
211     LOG(INFO) << "Skip package metadata check for ota type " << expected_ota_type;
212     return true;
213   }
214 
215   if (package_ota_type != expected_ota_type) {
216     LOG(ERROR) << "Unexpected ota package type, expects " << expected_ota_type << ", actual "
217                << package_ota_type;
218     return false;
219   }
220 
221   auto device = android::base::GetProperty("ro.product.device", "");
222   auto pkg_device = get_value(metadata, "pre-device");
223   // device name can be a | separated list, so need to check
224   if (pkg_device.empty() || !isInStringList(device, pkg_device, FINGERPRING_SEPARATOR)) {
225     LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << device;
226     return false;
227   }
228 
229   // We allow the package to not have any serialno; and we also allow it to carry multiple serial
230   // numbers split by "|"; e.g. serialno=serialno1|serialno2|serialno3 ... We will fail the
231   // verification if the device's serialno doesn't match any of these carried numbers.
232 
233   auto pkg_serial_no = get_value(metadata, "serialno");
234   if (!pkg_serial_no.empty()) {
235     auto device_serial_no = android::base::GetProperty("ro.serialno", "");
236     bool serial_number_match = false;
237     for (const auto& number : android::base::Split(pkg_serial_no, "|")) {
238       if (device_serial_no == android::base::Trim(number)) {
239         serial_number_match = true;
240       }
241     }
242     if (!serial_number_match) {
243       LOG(ERROR) << "Package is for serial " << pkg_serial_no;
244       return false;
245     }
246   } else if (ota_type == OtaType::BRICK) {
247     const auto device_build_tag = android::base::GetProperty("ro.build.tags", "");
248     if (device_build_tag.empty()) {
249       LOG(ERROR) << "Unable to determine device build tags, serial number is missing from package. "
250                     "Rejecting the brick OTA package.";
251       return false;
252     }
253     if (device_build_tag == RELEASE_KEYS_TAG) {
254       LOG(ERROR) << "Device is release key build, serial number is missing from package. "
255                     "Rejecting the brick OTA package.";
256       return false;
257     }
258     LOG(INFO)
259         << "Serial number is missing from brick OTA package, permitting anyway because device is "
260         << device_build_tag;
261   }
262 
263   if (ota_type == OtaType::AB) {
264     return CheckAbSpecificMetadata(metadata);
265   }
266 
267   return true;
268 }
269 
ExtractPayloadProperties(ZipArchiveHandle zip)270 static std::string ExtractPayloadProperties(ZipArchiveHandle zip) {
271   // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
272   // in the zip file.
273   static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
274   ZipEntry64 properties_entry;
275   if (FindEntry(zip, AB_OTA_PAYLOAD_PROPERTIES, &properties_entry) != 0) {
276     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
277     return {};
278   }
279   auto properties_entry_length = properties_entry.uncompressed_length;
280   if (properties_entry_length > std::numeric_limits<size_t>::max()) {
281     LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES
282                << " because's uncompressed size exceeds size of address space. "
283                << properties_entry_length;
284     return {};
285   }
286   std::string payload_properties(properties_entry_length, '\0');
287   int32_t err =
288       ExtractToMemory(zip, &properties_entry, reinterpret_cast<uint8_t*>(payload_properties.data()),
289                       properties_entry_length);
290   if (err != 0) {
291     LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
292     return {};
293   }
294   return payload_properties;
295 }
296 
SetUpAbUpdateCommands(const std::string & package,ZipArchiveHandle zip,int status_fd,std::vector<std::string> * cmd)297 bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd,
298                            std::vector<std::string>* cmd) {
299   CHECK(cmd != nullptr);
300 
301   // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
302   // in the zip file.
303   const auto payload_properties = ExtractPayloadProperties(zip);
304   if (payload_properties.empty()) {
305     return false;
306   }
307 
308   static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
309   ZipEntry64 payload_entry;
310   if (FindEntry(zip, AB_OTA_PAYLOAD, &payload_entry) != 0) {
311     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD;
312     return false;
313   }
314   long payload_offset = payload_entry.offset;
315   *cmd = {
316     "/system/bin/update_engine_sideload",
317     "--payload=file://" + package,
318     android::base::StringPrintf("--offset=%ld", payload_offset),
319     "--headers=" + std::string(payload_properties.begin(), payload_properties.end()),
320     android::base::StringPrintf("--status_fd=%d", status_fd),
321   };
322   return true;
323 }
324 
SetUpNonAbUpdateCommands(const std::string & package,ZipArchiveHandle zip,int retry_count,int status_fd,std::vector<std::string> * cmd)325 bool SetUpNonAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int retry_count,
326                               int status_fd, std::vector<std::string>* cmd) {
327   CHECK(cmd != nullptr);
328 
329   // In non-A/B updates we extract the update binary from the package.
330   static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
331   ZipEntry64 binary_entry;
332   if (FindEntry(zip, UPDATE_BINARY_NAME, &binary_entry) != 0) {
333     LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
334     return false;
335   }
336 
337   const std::string binary_path = Paths::Get().temporary_update_binary();
338   unlink(binary_path.c_str());
339   android::base::unique_fd fd(
340       open(binary_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755));
341   if (fd == -1) {
342     PLOG(ERROR) << "Failed to create " << binary_path;
343     return false;
344   }
345 
346   if (auto error = ExtractEntryToFile(zip, &binary_entry, fd); error != 0) {
347     LOG(ERROR) << "Failed to extract " << UPDATE_BINARY_NAME << ": " << ErrorCodeString(error);
348     return false;
349   }
350 
351   // When executing the update binary contained in the package, the arguments passed are:
352   //   - the version number for this interface
353   //   - an FD to which the program can write in order to update the progress bar.
354   //   - the name of the package zip file.
355   //   - an optional argument "retry" if this update is a retry of a failed update attempt.
356   *cmd = {
357     binary_path,
358     std::to_string(kRecoveryApiVersion),
359     std::to_string(status_fd),
360     package,
361   };
362   if (retry_count > 0) {
363     cmd->push_back("retry");
364   }
365   return true;
366 }
367 
log_max_temperature(int * max_temperature,const std::atomic<bool> & logger_finished)368 static void log_max_temperature(int* max_temperature, const std::atomic<bool>& logger_finished) {
369   CHECK(max_temperature != nullptr);
370   std::mutex mtx;
371   std::unique_lock<std::mutex> lck(mtx);
372   while (!logger_finished.load() &&
373          finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
374     *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
375   }
376 }
377 
PerformPowerwashIfRequired(ZipArchiveHandle zip,Device * device)378 static bool PerformPowerwashIfRequired(ZipArchiveHandle zip, Device *device) {
379   const auto payload_properties = ExtractPayloadProperties(zip);
380   if (payload_properties.find("POWERWASH=1") != std::string::npos) {
381     LOG(INFO) << "Payload properties has POWERWASH=1, wiping userdata...";
382     return WipeData(device);
383   }
384   return true;
385 }
386 
387 // If the package contains an update binary, extract it and run it.
TryUpdateBinary(Package * package,bool * wipe_cache,std::vector<std::string> * log_buffer,int retry_count,int * max_temperature,Device * device)388 static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
389                                      std::vector<std::string>* log_buffer, int retry_count,
390                                      int* max_temperature, Device* device) {
391   auto ui = device->GetUI();
392   std::map<std::string, std::string> metadata;
393   auto zip = package->GetZipArchiveHandle();
394   if (!ReadMetadataFromPackage(zip, &metadata)) {
395     LOG(ERROR) << "Failed to parse metadata in the zip file";
396     return INSTALL_CORRUPT;
397   }
398 
399   const bool package_is_ab = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::AB);
400   const bool package_is_brick = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::BRICK);
401   if (package_is_brick) {
402     LOG(INFO) << "Installing a brick package";
403     if (package->GetType() == PackageType::kFile &&
404         package->GetPackageSize() < MEMORY_PACKAGE_LIMIT) {
405       std::vector<uint8_t> content(package->GetPackageSize());
406       if (package->ReadFullyAtOffset(content.data(), content.size(), 0)) {
407         auto memory_package = Package::CreateMemoryPackage(std::move(content), {});
408         return WipeAbDevice(device, memory_package.get()) ? INSTALL_SUCCESS : INSTALL_ERROR;
409       }
410     }
411     return WipeAbDevice(device, package) ? INSTALL_SUCCESS : INSTALL_ERROR;
412   }
413   bool device_supports_ab = android::base::GetBoolProperty("ro.build.ab_update", false);
414   bool ab_device_supports_nonab =
415       android::base::GetBoolProperty("ro.virtual_ab.allow_non_ab", false);
416   bool device_only_supports_ab = device_supports_ab && !ab_device_supports_nonab;
417 
418   const auto current_spl = android::base::GetProperty("ro.build.version.security_patch", "");
419   if (ViolatesSPLDowngrade(zip, current_spl)) {
420     LOG(ERROR) << "Denying OTA because it's SPL downgrade";
421     return INSTALL_ERROR;
422   }
423 
424   if (package_is_ab) {
425     CHECK(package->GetType() == PackageType::kFile);
426   }
427 
428   // Verify against the metadata in the package first. Expects A/B metadata if:
429   // Package declares itself as an A/B package
430   // Package does not declare itself as an A/B package, but device only supports A/B;
431   //   still calls CheckPackageMetadata to get a meaningful error message.
432   if (package_is_ab || device_only_supports_ab) {
433     if (!CheckPackageMetadata(metadata, OtaType::AB)) {
434       log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
435       return INSTALL_ERROR;
436     }
437   }
438 
439   ReadSourceTargetBuild(metadata, log_buffer);
440 
441   // The updater in child process writes to the pipe to communicate with recovery.
442   android::base::unique_fd pipe_read, pipe_write;
443   // Explicitly disable O_CLOEXEC using 0 as the flags (last) parameter to Pipe
444   // so that the child updater process will recieve a non-closed fd.
445   if (!android::base::Pipe(&pipe_read, &pipe_write, 0)) {
446     PLOG(ERROR) << "Failed to create pipe for updater-recovery communication";
447     return INSTALL_CORRUPT;
448   }
449 
450   // The updater-recovery communication protocol.
451   //
452   //   progress <frac> <secs>
453   //       fill up the next <frac> part of of the progress bar over <secs> seconds. If <secs> is
454   //       zero, use `set_progress` commands to manually control the progress of this segment of the
455   //       bar.
456   //
457   //   set_progress <frac>
458   //       <frac> should be between 0.0 and 1.0; sets the progress bar within the segment defined by
459   //       the most recent progress command.
460   //
461   //   ui_print <string>
462   //       display <string> on the screen.
463   //
464   //   wipe_cache
465   //       a wipe of cache will be performed following a successful installation.
466   //
467   //   clear_display
468   //       turn off the text display.
469   //
470   //   enable_reboot
471   //       packages can explicitly request that they want the user to be able to reboot during
472   //       installation (useful for debugging packages that don't exit).
473   //
474   //   retry_update
475   //       updater encounters some issue during the update. It requests a reboot to retry the same
476   //       package automatically.
477   //
478   //   log <string>
479   //       updater requests logging the string (e.g. cause of the failure).
480   //
481 
482   std::string package_path = package->GetPath();
483 
484   std::vector<std::string> args;
485   if (auto setup_result =
486           package_is_ab
487               ? SetUpAbUpdateCommands(package_path, zip, pipe_write.get(), &args)
488               : SetUpNonAbUpdateCommands(package_path, zip, retry_count, pipe_write.get(), &args);
489       !setup_result) {
490     log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
491     return INSTALL_CORRUPT;
492   }
493 
494   pid_t pid = fork();
495   if (pid == -1) {
496     PLOG(ERROR) << "Failed to fork update binary";
497     log_buffer->push_back(android::base::StringPrintf("error: %d", kForkUpdateBinaryFailure));
498     return INSTALL_ERROR;
499   }
500 
501   if (pid == 0) {
502     umask(022);
503     pipe_read.reset();
504 
505     // Convert the std::string vector to a NULL-terminated char* vector suitable for execv.
506     auto chr_args = StringVectorToNullTerminatedArray(args);
507     execv(chr_args[0], chr_args.data());
508     // We shouldn't use LOG/PLOG in the forked process, since they may cause the child process to
509     // hang. This deadlock results from an improperly copied mutex in the ui functions.
510     // (Bug: 34769056)
511     fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
512     _exit(EXIT_FAILURE);
513   }
514   pipe_write.reset();
515 
516   std::atomic<bool> logger_finished(false);
517   std::thread temperature_logger(log_max_temperature, max_temperature, std::ref(logger_finished));
518 
519   *wipe_cache = false;
520   bool retry_update = false;
521 
522   char buffer[1024];
523   FILE* from_child = android::base::Fdopen(std::move(pipe_read), "r");
524   while (fgets(buffer, sizeof(buffer), from_child) != nullptr) {
525     std::string line(buffer);
526     size_t space = line.find_first_of(" \n");
527     std::string command(line.substr(0, space));
528     if (command.empty()) continue;
529 
530     // Get rid of the leading and trailing space and/or newline.
531     std::string args = space == std::string::npos ? "" : android::base::Trim(line.substr(space));
532 
533     if (command == "progress") {
534       std::vector<std::string> tokens = android::base::Split(args, " ");
535       double fraction;
536       int seconds;
537       if (tokens.size() == 2 && android::base::ParseDouble(tokens[0].c_str(), &fraction) &&
538           android::base::ParseInt(tokens[1], &seconds)) {
539         ui->ShowProgress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
540       } else {
541         LOG(ERROR) << "invalid \"progress\" parameters: " << line;
542       }
543     } else if (command == "set_progress") {
544       std::vector<std::string> tokens = android::base::Split(args, " ");
545       double fraction;
546       if (tokens.size() == 1 && android::base::ParseDouble(tokens[0].c_str(), &fraction)) {
547         ui->SetProgress(fraction);
548       } else {
549         LOG(ERROR) << "invalid \"set_progress\" parameters: " << line;
550       }
551     } else if (command == "ui_print") {
552       ui->PrintOnScreenOnly("%s\n", args.c_str());
553       fflush(stdout);
554     } else if (command == "wipe_cache") {
555       *wipe_cache = true;
556     } else if (command == "clear_display") {
557       ui->SetBackground(RecoveryUI::NONE);
558     } else if (command == "enable_reboot") {
559       // packages can explicitly request that they want the user
560       // to be able to reboot during installation (useful for
561       // debugging packages that don't exit).
562       ui->SetEnableReboot(true);
563     } else if (command == "retry_update") {
564       retry_update = true;
565     } else if (command == "log") {
566       if (!args.empty()) {
567         // Save the logging request from updater and write to last_install later.
568         log_buffer->push_back(args);
569       } else {
570         LOG(ERROR) << "invalid \"log\" parameters: " << line;
571       }
572     } else {
573       LOG(ERROR) << "unknown command [" << command << "]";
574     }
575   }
576   fclose(from_child);
577 
578   int status;
579   waitpid(pid, &status, 0);
580 
581   logger_finished.store(true);
582   finish_log_temperature.notify_one();
583   temperature_logger.join();
584 
585   if (retry_update) {
586     return INSTALL_RETRY;
587   }
588   if (WIFEXITED(status)) {
589     if (WEXITSTATUS(status) != EXIT_SUCCESS) {
590       LOG(ERROR) << "Error in " << package_path << " (status " << WEXITSTATUS(status) << ")";
591       return INSTALL_ERROR;
592     }
593   } else if (WIFSIGNALED(status)) {
594     LOG(ERROR) << "Error in " << package_path << " (killed by signal " << WTERMSIG(status) << ")";
595     return INSTALL_ERROR;
596   } else {
597     LOG(FATAL) << "Invalid status code " << status;
598   }
599   if (package_is_ab) {
600     PerformPowerwashIfRequired(zip, device);
601   }
602 
603   return INSTALL_SUCCESS;
604 }
605 
VerifyAndInstallPackage(Package * package,bool * wipe_cache,std::vector<std::string> * log_buffer,int retry_count,int * max_temperature,Device * device)606 static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache,
607                                              std::vector<std::string>* log_buffer, int retry_count,
608                                              int* max_temperature, Device* device) {
609   auto ui = device->GetUI();
610   ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
611   // Give verification half the progress bar...
612   ui->SetProgressType(RecoveryUI::DETERMINATE);
613   ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
614 
615   // Verify package.
616   if (!verify_package(package, ui)) {
617     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
618     return INSTALL_CORRUPT;
619   }
620 
621   // Verify and install the contents of the package.
622   ui->Print("Installing update...\n");
623   if (retry_count > 0) {
624     ui->Print("Retry attempt: %d\n", retry_count);
625   }
626   ui->SetEnableReboot(false);
627   auto result =
628       TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, device);
629   ui->SetEnableReboot(true);
630   ui->Print("\n");
631 
632   return result;
633 }
634 
InstallPackage(Package * package,const std::string_view package_id,bool should_wipe_cache,int retry_count,Device * device)635 InstallResult InstallPackage(Package* package, const std::string_view package_id,
636                              bool should_wipe_cache, int retry_count, Device* device) {
637   auto ui = device->GetUI();
638   auto start = std::chrono::system_clock::now();
639 
640   int start_temperature = GetMaxValueFromThermalZone();
641   int max_temperature = start_temperature;
642 
643   InstallResult result;
644   std::vector<std::string> log_buffer;
645 
646   ui->Print("Supported API: %d\n", kRecoveryApiVersion);
647 
648   ui->Print("Finding update package...\n");
649   LOG(INFO) << "Update package id: " << package_id;
650   if (!package) {
651     log_buffer.push_back(android::base::StringPrintf("error: %d", kMapFileFailure));
652     result = INSTALL_CORRUPT;
653   } else if (setup_install_mounts() != 0) {
654     LOG(ERROR) << "failed to set up expected mounts for install; aborting";
655     result = INSTALL_ERROR;
656   } else {
657     bool updater_wipe_cache = false;
658     result = VerifyAndInstallPackage(package, &updater_wipe_cache, &log_buffer, retry_count,
659                                      &max_temperature, device);
660     should_wipe_cache = should_wipe_cache || updater_wipe_cache;
661   }
662 
663   // Measure the time spent to apply OTA update in seconds.
664   std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
665   int time_total = static_cast<int>(duration.count());
666 
667   bool has_cache = volume_for_mount_point("/cache") != nullptr;
668   // Skip logging the uncrypt_status on devices without /cache.
669   if (has_cache) {
670     static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
671     if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
672       LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
673     } else {
674       std::string uncrypt_status;
675       if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
676         PLOG(WARNING) << "failed to read uncrypt status";
677       } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
678         LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
679       } else {
680         log_buffer.push_back(android::base::Trim(uncrypt_status));
681       }
682     }
683   }
684 
685   // The first two lines need to be the package name and install result.
686   std::vector<std::string> log_header = {
687     std::string(package_id),
688     result == INSTALL_SUCCESS ? "1" : "0",
689     "time_total: " + std::to_string(time_total),
690     "retry: " + std::to_string(retry_count),
691   };
692 
693   int end_temperature = GetMaxValueFromThermalZone();
694   max_temperature = std::max(end_temperature, max_temperature);
695   if (start_temperature > 0) {
696     log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
697   }
698   if (end_temperature > 0) {
699     log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
700   }
701   if (max_temperature > 0) {
702     log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
703   }
704 
705   std::string log_content =
706       android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n") + "\n";
707   const std::string& install_file = Paths::Get().temporary_install_file();
708   if (!android::base::WriteStringToFile(log_content, install_file)) {
709     PLOG(ERROR) << "failed to write " << install_file;
710   }
711 
712   // Write a copy into last_log.
713   LOG(INFO) << log_content;
714 
715   if (result == INSTALL_SUCCESS && should_wipe_cache) {
716     if (!WipeCache(ui, nullptr)) {
717       result = INSTALL_ERROR;
718     }
719   }
720 
721   return result;
722 }
723 
verify_package(Package * package,RecoveryUI * ui)724 bool verify_package(Package* package, RecoveryUI* ui) {
725   static constexpr const char* CERTIFICATE_ZIP_FILE = "/system/etc/security/otacerts.zip";
726   std::vector<Certificate> loaded_keys = LoadKeysFromZipfile(CERTIFICATE_ZIP_FILE);
727   if (loaded_keys.empty()) {
728     LOG(ERROR) << "Failed to load keys";
729     return false;
730   }
731   LOG(INFO) << loaded_keys.size() << " key(s) loaded from " << CERTIFICATE_ZIP_FILE;
732 
733   // Verify package.
734   ui->Print("Verifying update package...\n");
735   auto t0 = std::chrono::system_clock::now();
736   int err = verify_file(package, loaded_keys);
737   std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
738   ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
739   if (err != VERIFY_SUCCESS) {
740     LOG(ERROR) << "Signature verification failed";
741     LOG(ERROR) << "error: " << kZipVerificationFailure;
742     return false;
743   }
744   return true;
745 }
746 
SetupPackageMount(const std::string & package_path,bool * should_use_fuse)747 bool SetupPackageMount(const std::string& package_path, bool* should_use_fuse) {
748   CHECK(should_use_fuse != nullptr);
749 
750   if (package_path.empty()) {
751     return false;
752   }
753 
754   *should_use_fuse = true;
755   if (package_path[0] == '@') {
756     auto block_map_path = package_path.substr(1);
757     if (ensure_path_mounted(block_map_path) != 0) {
758       LOG(ERROR) << "Failed to mount " << block_map_path;
759       return false;
760     }
761     // uncrypt only produces block map only if the package stays on /data.
762     *should_use_fuse = false;
763     return true;
764   }
765 
766   // Package is not a block map file.
767   if (ensure_path_mounted(package_path) != 0) {
768     LOG(ERROR) << "Failed to mount " << package_path;
769     return false;
770   }
771 
772   // Reject the package if the input path doesn't equal the canonicalized path.
773   // e.g. /cache/../sdcard/update_package.
774   std::error_code ec;
775   auto canonical_path = std::filesystem::canonical(package_path, ec);
776   if (ec) {
777     LOG(ERROR) << "Failed to get canonical of " << package_path << ", " << ec.message();
778     return false;
779   }
780   if (canonical_path.string() != package_path) {
781     LOG(ERROR) << "Installation aborts. The canonical path " << canonical_path.string()
782                << " doesn't equal the original path " << package_path;
783     return false;
784   }
785 
786   constexpr const char* CACHE_ROOT = "/cache";
787   if (android::base::StartsWith(package_path, CACHE_ROOT)) {
788     *should_use_fuse = false;
789   }
790   return true;
791 }
792 
793 // Check if `target_token` is in string `str_list`, where `str_list` is expected to be a
794 // list delimited by `deliminator`
795 // E.X. isInStringList("a", "a|b|c|d", "|") => true
796 // E.X. isInStringList("abc", "abc", "|") => true
isInStringList(const std::string & target_token,const std::string & str_list,const std::string & deliminator)797 static bool isInStringList(const std::string& target_token, const std::string& str_list,
798                            const std::string& deliminator) {
799   if (target_token.length() > str_list.length()) {
800     return false;
801   } else if (target_token.length() == str_list.length() || deliminator.length() == 0) {
802     return target_token == str_list;
803   }
804   auto&& list = android::base::Split(str_list, deliminator);
805   return std::find(list.begin(), list.end(), target_token) != list.end();
806 }
807