Home | History | Annotate | Download | only in recovery
      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.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 <functional>
     34 #include <limits>
     35 #include <map>
     36 #include <mutex>
     37 #include <string>
     38 #include <thread>
     39 #include <vector>
     40 
     41 #include <android-base/file.h>
     42 #include <android-base/logging.h>
     43 #include <android-base/parsedouble.h>
     44 #include <android-base/parseint.h>
     45 #include <android-base/properties.h>
     46 #include <android-base/stringprintf.h>
     47 #include <android-base/strings.h>
     48 #include <vintf/VintfObjectRecovery.h>
     49 #include <ziparchive/zip_archive.h>
     50 
     51 #include "common.h"
     52 #include "error_code.h"
     53 #include "otautil/SysUtil.h"
     54 #include "otautil/ThermalUtil.h"
     55 #include "private/install.h"
     56 #include "roots.h"
     57 #include "ui.h"
     58 #include "verifier.h"
     59 
     60 using namespace std::chrono_literals;
     61 
     62 // Default allocation of progress bar segments to operations
     63 static constexpr int VERIFICATION_PROGRESS_TIME = 60;
     64 static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
     65 
     66 static std::condition_variable finish_log_temperature;
     67 
     68 // This function parses and returns the build.version.incremental
     69 static std::string parse_build_number(const std::string& str) {
     70     size_t pos = str.find('=');
     71     if (pos != std::string::npos) {
     72         return android::base::Trim(str.substr(pos+1));
     73     }
     74 
     75     LOG(ERROR) << "Failed to parse build number in " << str;
     76     return "";
     77 }
     78 
     79 bool read_metadata_from_package(ZipArchiveHandle zip, std::string* metadata) {
     80   CHECK(metadata != nullptr);
     81 
     82   static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
     83   ZipString path(METADATA_PATH);
     84   ZipEntry entry;
     85   if (FindEntry(zip, path, &entry) != 0) {
     86     LOG(ERROR) << "Failed to find " << METADATA_PATH;
     87     return false;
     88   }
     89 
     90   uint32_t length = entry.uncompressed_length;
     91   metadata->resize(length, '\0');
     92   int32_t err = ExtractToMemory(zip, &entry, reinterpret_cast<uint8_t*>(&(*metadata)[0]), length);
     93   if (err != 0) {
     94     LOG(ERROR) << "Failed to extract " << METADATA_PATH << ": " << ErrorCodeString(err);
     95     return false;
     96   }
     97   return true;
     98 }
     99 
    100 // Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
    101 static void read_source_target_build(ZipArchiveHandle zip, std::vector<std::string>* log_buffer) {
    102   std::string metadata;
    103   if (!read_metadata_from_package(zip, &metadata)) {
    104     return;
    105   }
    106   // Examples of the pre-build and post-build strings in metadata:
    107   //   pre-build-incremental=2943039
    108   //   post-build-incremental=2951741
    109   std::vector<std::string> lines = android::base::Split(metadata, "\n");
    110   for (const std::string& line : lines) {
    111     std::string str = android::base::Trim(line);
    112     if (android::base::StartsWith(str, "pre-build-incremental")) {
    113       std::string source_build = parse_build_number(str);
    114       if (!source_build.empty()) {
    115         log_buffer->push_back("source_build: " + source_build);
    116       }
    117     } else if (android::base::StartsWith(str, "post-build-incremental")) {
    118       std::string target_build = parse_build_number(str);
    119       if (!target_build.empty()) {
    120         log_buffer->push_back("target_build: " + target_build);
    121       }
    122     }
    123   }
    124 }
    125 
    126 #ifdef AB_OTA_UPDATER
    127 
    128 // Parses the metadata of the OTA package in |zip| and checks whether we are
    129 // allowed to accept this A/B package. Downgrading is not allowed unless
    130 // explicitly enabled in the package and only for incremental packages.
    131 static int check_newer_ab_build(ZipArchiveHandle zip) {
    132   std::string metadata_str;
    133   if (!read_metadata_from_package(zip, &metadata_str)) {
    134     return INSTALL_CORRUPT;
    135   }
    136   std::map<std::string, std::string> metadata;
    137   for (const std::string& line : android::base::Split(metadata_str, "\n")) {
    138     size_t eq = line.find('=');
    139     if (eq != std::string::npos) {
    140       metadata[line.substr(0, eq)] = line.substr(eq + 1);
    141     }
    142   }
    143 
    144   std::string value = android::base::GetProperty("ro.product.device", "");
    145   const std::string& pkg_device = metadata["pre-device"];
    146   if (pkg_device != value || pkg_device.empty()) {
    147     LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << value;
    148     return INSTALL_ERROR;
    149   }
    150 
    151   // We allow the package to not have any serialno, but if it has a non-empty
    152   // value it should match.
    153   value = android::base::GetProperty("ro.serialno", "");
    154   const std::string& pkg_serial_no = metadata["serialno"];
    155   if (!pkg_serial_no.empty() && pkg_serial_no != value) {
    156     LOG(ERROR) << "Package is for serial " << pkg_serial_no;
    157     return INSTALL_ERROR;
    158   }
    159 
    160   if (metadata["ota-type"] != "AB") {
    161     LOG(ERROR) << "Package is not A/B";
    162     return INSTALL_ERROR;
    163   }
    164 
    165   // Incremental updates should match the current build.
    166   value = android::base::GetProperty("ro.build.version.incremental", "");
    167   const std::string& pkg_pre_build = metadata["pre-build-incremental"];
    168   if (!pkg_pre_build.empty() && pkg_pre_build != value) {
    169     LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected " << value;
    170     return INSTALL_ERROR;
    171   }
    172 
    173   value = android::base::GetProperty("ro.build.fingerprint", "");
    174   const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
    175   if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != value) {
    176     LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected "
    177                << value;
    178     return INSTALL_ERROR;
    179   }
    180 
    181   // Check for downgrade version.
    182   int64_t build_timestamp =
    183       android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
    184   int64_t pkg_post_timestamp = 0;
    185   // We allow to full update to the same version we are running, in case there
    186   // is a problem with the current copy of that version.
    187   if (metadata["post-timestamp"].empty() ||
    188       !android::base::ParseInt(metadata["post-timestamp"].c_str(), &pkg_post_timestamp) ||
    189       pkg_post_timestamp < build_timestamp) {
    190     if (metadata["ota-downgrade"] != "yes") {
    191       LOG(ERROR) << "Update package is older than the current build, expected a build "
    192                     "newer than timestamp "
    193                  << build_timestamp << " but package has timestamp " << pkg_post_timestamp
    194                  << " and downgrade not allowed.";
    195       return INSTALL_ERROR;
    196     }
    197     if (pkg_pre_build_fingerprint.empty()) {
    198       LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
    199       return INSTALL_ERROR;
    200     }
    201   }
    202 
    203   return 0;
    204 }
    205 
    206 int update_binary_command(const std::string& package, ZipArchiveHandle zip,
    207                           const std::string& binary_path, int /* retry_count */, int status_fd,
    208                           std::vector<std::string>* cmd) {
    209   CHECK(cmd != nullptr);
    210   int ret = check_newer_ab_build(zip);
    211   if (ret != 0) {
    212     return ret;
    213   }
    214 
    215   // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
    216   // in the zip file.
    217   static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
    218   ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES);
    219   ZipEntry properties_entry;
    220   if (FindEntry(zip, property_name, &properties_entry) != 0) {
    221     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
    222     return INSTALL_CORRUPT;
    223   }
    224   uint32_t properties_entry_length = properties_entry.uncompressed_length;
    225   std::vector<uint8_t> payload_properties(properties_entry_length);
    226   int32_t err =
    227       ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length);
    228   if (err != 0) {
    229     LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
    230     return INSTALL_CORRUPT;
    231   }
    232 
    233   static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
    234   ZipString payload_name(AB_OTA_PAYLOAD);
    235   ZipEntry payload_entry;
    236   if (FindEntry(zip, payload_name, &payload_entry) != 0) {
    237     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD;
    238     return INSTALL_CORRUPT;
    239   }
    240   long payload_offset = payload_entry.offset;
    241   *cmd = {
    242     binary_path,
    243     "--payload=file://" + package,
    244     android::base::StringPrintf("--offset=%ld", payload_offset),
    245     "--headers=" + std::string(payload_properties.begin(), payload_properties.end()),
    246     android::base::StringPrintf("--status_fd=%d", status_fd),
    247   };
    248   return 0;
    249 }
    250 
    251 #else  // !AB_OTA_UPDATER
    252 
    253 int update_binary_command(const std::string& package, ZipArchiveHandle zip,
    254                           const std::string& binary_path, int retry_count, int status_fd,
    255                           std::vector<std::string>* cmd) {
    256   CHECK(cmd != nullptr);
    257 
    258   // On traditional updates we extract the update binary from the package.
    259   static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
    260   ZipString binary_name(UPDATE_BINARY_NAME);
    261   ZipEntry binary_entry;
    262   if (FindEntry(zip, binary_name, &binary_entry) != 0) {
    263     LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
    264     return INSTALL_CORRUPT;
    265   }
    266 
    267   unlink(binary_path.c_str());
    268   int fd = open(binary_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755);
    269   if (fd == -1) {
    270     PLOG(ERROR) << "Failed to create " << binary_path;
    271     return INSTALL_ERROR;
    272   }
    273 
    274   int32_t error = ExtractEntryToFile(zip, &binary_entry, fd);
    275   close(fd);
    276   if (error != 0) {
    277     LOG(ERROR) << "Failed to extract " << UPDATE_BINARY_NAME << ": " << ErrorCodeString(error);
    278     return INSTALL_ERROR;
    279   }
    280 
    281   *cmd = {
    282     binary_path,
    283     EXPAND(RECOVERY_API_VERSION),  // defined in Android.mk
    284     std::to_string(status_fd),
    285     package,
    286   };
    287   if (retry_count > 0) {
    288     cmd->push_back("retry");
    289   }
    290   return 0;
    291 }
    292 #endif  // !AB_OTA_UPDATER
    293 
    294 static void log_max_temperature(int* max_temperature, const std::atomic<bool>& logger_finished) {
    295   CHECK(max_temperature != nullptr);
    296   std::mutex mtx;
    297   std::unique_lock<std::mutex> lck(mtx);
    298   while (!logger_finished.load() &&
    299          finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
    300     *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
    301   }
    302 }
    303 
    304 // If the package contains an update binary, extract it and run it.
    305 static int try_update_binary(const std::string& package, ZipArchiveHandle zip, bool* wipe_cache,
    306                              std::vector<std::string>* log_buffer, int retry_count,
    307                              int* max_temperature) {
    308   read_source_target_build(zip, log_buffer);
    309 
    310   int pipefd[2];
    311   pipe(pipefd);
    312 
    313   std::vector<std::string> args;
    314 #ifdef AB_OTA_UPDATER
    315   int ret = update_binary_command(package, zip, "/sbin/update_engine_sideload", retry_count,
    316                                   pipefd[1], &args);
    317 #else
    318   int ret = update_binary_command(package, zip, "/tmp/update-binary", retry_count, pipefd[1],
    319                                   &args);
    320 #endif
    321   if (ret) {
    322     close(pipefd[0]);
    323     close(pipefd[1]);
    324     return ret;
    325   }
    326 
    327   // When executing the update binary contained in the package, the
    328   // arguments passed are:
    329   //
    330   //   - the version number for this interface
    331   //
    332   //   - an FD to which the program can write in order to update the
    333   //     progress bar.  The program can write single-line commands:
    334   //
    335   //        progress <frac> <secs>
    336   //            fill up the next <frac> part of of the progress bar
    337   //            over <secs> seconds.  If <secs> is zero, use
    338   //            set_progress commands to manually control the
    339   //            progress of this segment of the bar.
    340   //
    341   //        set_progress <frac>
    342   //            <frac> should be between 0.0 and 1.0; sets the
    343   //            progress bar within the segment defined by the most
    344   //            recent progress command.
    345   //
    346   //        ui_print <string>
    347   //            display <string> on the screen.
    348   //
    349   //        wipe_cache
    350   //            a wipe of cache will be performed following a successful
    351   //            installation.
    352   //
    353   //        clear_display
    354   //            turn off the text display.
    355   //
    356   //        enable_reboot
    357   //            packages can explicitly request that they want the user
    358   //            to be able to reboot during installation (useful for
    359   //            debugging packages that don't exit).
    360   //
    361   //        retry_update
    362   //            updater encounters some issue during the update. It requests
    363   //            a reboot to retry the same package automatically.
    364   //
    365   //        log <string>
    366   //            updater requests logging the string (e.g. cause of the
    367   //            failure).
    368   //
    369   //   - the name of the package zip file.
    370   //
    371   //   - an optional argument "retry" if this update is a retry of a failed
    372   //   update attempt.
    373   //
    374 
    375   // Convert the vector to a NULL-terminated char* array suitable for execv.
    376   const char* chr_args[args.size() + 1];
    377   chr_args[args.size()] = nullptr;
    378   for (size_t i = 0; i < args.size(); i++) {
    379     chr_args[i] = args[i].c_str();
    380   }
    381 
    382   pid_t pid = fork();
    383 
    384   if (pid == -1) {
    385     close(pipefd[0]);
    386     close(pipefd[1]);
    387     PLOG(ERROR) << "Failed to fork update binary";
    388     return INSTALL_ERROR;
    389   }
    390 
    391   if (pid == 0) {
    392     umask(022);
    393     close(pipefd[0]);
    394     execv(chr_args[0], const_cast<char**>(chr_args));
    395     // Bug: 34769056
    396     // We shouldn't use LOG/PLOG in the forked process, since they may cause
    397     // the child process to hang. This deadlock results from an improperly
    398     // copied mutex in the ui functions.
    399     fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
    400     _exit(EXIT_FAILURE);
    401   }
    402   close(pipefd[1]);
    403 
    404   std::atomic<bool> logger_finished(false);
    405   std::thread temperature_logger(log_max_temperature, max_temperature, std::ref(logger_finished));
    406 
    407   *wipe_cache = false;
    408   bool retry_update = false;
    409 
    410   char buffer[1024];
    411   FILE* from_child = fdopen(pipefd[0], "r");
    412   while (fgets(buffer, sizeof(buffer), from_child) != nullptr) {
    413     std::string line(buffer);
    414     size_t space = line.find_first_of(" \n");
    415     std::string command(line.substr(0, space));
    416     if (command.empty()) continue;
    417 
    418     // Get rid of the leading and trailing space and/or newline.
    419     std::string args = space == std::string::npos ? "" : android::base::Trim(line.substr(space));
    420 
    421     if (command == "progress") {
    422       std::vector<std::string> tokens = android::base::Split(args, " ");
    423       double fraction;
    424       int seconds;
    425       if (tokens.size() == 2 && android::base::ParseDouble(tokens[0].c_str(), &fraction) &&
    426           android::base::ParseInt(tokens[1], &seconds)) {
    427         ui->ShowProgress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
    428       } else {
    429         LOG(ERROR) << "invalid \"progress\" parameters: " << line;
    430       }
    431     } else if (command == "set_progress") {
    432       std::vector<std::string> tokens = android::base::Split(args, " ");
    433       double fraction;
    434       if (tokens.size() == 1 && android::base::ParseDouble(tokens[0].c_str(), &fraction)) {
    435         ui->SetProgress(fraction);
    436       } else {
    437         LOG(ERROR) << "invalid \"set_progress\" parameters: " << line;
    438       }
    439     } else if (command == "ui_print") {
    440       ui->PrintOnScreenOnly("%s\n", args.c_str());
    441       fflush(stdout);
    442     } else if (command == "wipe_cache") {
    443       *wipe_cache = true;
    444     } else if (command == "clear_display") {
    445       ui->SetBackground(RecoveryUI::NONE);
    446     } else if (command == "enable_reboot") {
    447       // packages can explicitly request that they want the user
    448       // to be able to reboot during installation (useful for
    449       // debugging packages that don't exit).
    450       ui->SetEnableReboot(true);
    451     } else if (command == "retry_update") {
    452       retry_update = true;
    453     } else if (command == "log") {
    454       if (!args.empty()) {
    455         // Save the logging request from updater and write to last_install later.
    456         log_buffer->push_back(args);
    457       } else {
    458         LOG(ERROR) << "invalid \"log\" parameters: " << line;
    459       }
    460     } else {
    461       LOG(ERROR) << "unknown command [" << command << "]";
    462     }
    463   }
    464   fclose(from_child);
    465 
    466   int status;
    467   waitpid(pid, &status, 0);
    468 
    469   logger_finished.store(true);
    470   finish_log_temperature.notify_one();
    471   temperature_logger.join();
    472 
    473   if (retry_update) {
    474     return INSTALL_RETRY;
    475   }
    476   if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
    477     LOG(ERROR) << "Error in " << package << " (Status " << WEXITSTATUS(status) << ")";
    478     return INSTALL_ERROR;
    479   }
    480 
    481   return INSTALL_SUCCESS;
    482 }
    483 
    484 // Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
    485 // entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
    486 // package.
    487 bool verify_package_compatibility(ZipArchiveHandle package_zip) {
    488   LOG(INFO) << "Verifying package compatibility...";
    489 
    490   static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
    491   ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
    492   ZipEntry compatibility_entry;
    493   if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) {
    494     LOG(INFO) << "Package doesn't contain " << COMPATIBILITY_ZIP_ENTRY << " entry";
    495     return true;
    496   }
    497 
    498   std::string zip_content(compatibility_entry.uncompressed_length, '\0');
    499   int32_t ret;
    500   if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
    501                              reinterpret_cast<uint8_t*>(&zip_content[0]),
    502                              compatibility_entry.uncompressed_length)) != 0) {
    503     LOG(ERROR) << "Failed to read " << COMPATIBILITY_ZIP_ENTRY << ": " << ErrorCodeString(ret);
    504     return false;
    505   }
    506 
    507   ZipArchiveHandle zip_handle;
    508   ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
    509                               zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
    510   if (ret != 0) {
    511     LOG(ERROR) << "Failed to OpenArchiveFromMemory: " << ErrorCodeString(ret);
    512     return false;
    513   }
    514 
    515   // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
    516   void* cookie;
    517   ret = StartIteration(zip_handle, &cookie, nullptr, nullptr);
    518   if (ret != 0) {
    519     LOG(ERROR) << "Failed to start iterating zip entries: " << ErrorCodeString(ret);
    520     CloseArchive(zip_handle);
    521     return false;
    522   }
    523   std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
    524 
    525   std::vector<std::string> compatibility_info;
    526   ZipEntry info_entry;
    527   ZipString info_name;
    528   while (Next(cookie, &info_entry, &info_name) == 0) {
    529     std::string content(info_entry.uncompressed_length, '\0');
    530     int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
    531                                   info_entry.uncompressed_length);
    532     if (ret != 0) {
    533       LOG(ERROR) << "Failed to read " << info_name.name << ": " << ErrorCodeString(ret);
    534       CloseArchive(zip_handle);
    535       return false;
    536     }
    537     compatibility_info.emplace_back(std::move(content));
    538   }
    539   CloseArchive(zip_handle);
    540 
    541   // VintfObjectRecovery::CheckCompatibility returns zero on success.
    542   std::string err;
    543   int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
    544   if (result == 0) {
    545     return true;
    546   }
    547 
    548   LOG(ERROR) << "Failed to verify package compatibility (result " << result << "): " << err;
    549   return false;
    550 }
    551 
    552 static int really_install_package(const std::string& path, bool* wipe_cache, bool needs_mount,
    553                                   std::vector<std::string>* log_buffer, int retry_count,
    554                                   int* max_temperature) {
    555   ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
    556   ui->Print("Finding update package...\n");
    557   // Give verification half the progress bar...
    558   ui->SetProgressType(RecoveryUI::DETERMINATE);
    559   ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
    560   LOG(INFO) << "Update location: " << path;
    561 
    562   // Map the update package into memory.
    563   ui->Print("Opening update package...\n");
    564 
    565   if (needs_mount) {
    566     if (path[0] == '@') {
    567       ensure_path_mounted(path.substr(1).c_str());
    568     } else {
    569       ensure_path_mounted(path.c_str());
    570     }
    571   }
    572 
    573   MemMapping map;
    574   if (!map.MapFile(path)) {
    575     LOG(ERROR) << "failed to map file";
    576     return INSTALL_CORRUPT;
    577   }
    578 
    579   // Verify package.
    580   if (!verify_package(map.addr, map.length)) {
    581     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
    582     return INSTALL_CORRUPT;
    583   }
    584 
    585   // Try to open the package.
    586   ZipArchiveHandle zip;
    587   int err = OpenArchiveFromMemory(map.addr, map.length, path.c_str(), &zip);
    588   if (err != 0) {
    589     LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err);
    590     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
    591 
    592     CloseArchive(zip);
    593     return INSTALL_CORRUPT;
    594   }
    595 
    596   // Additionally verify the compatibility of the package.
    597   if (!verify_package_compatibility(zip)) {
    598     log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
    599     CloseArchive(zip);
    600     return INSTALL_CORRUPT;
    601   }
    602 
    603   // Verify and install the contents of the package.
    604   ui->Print("Installing update...\n");
    605   if (retry_count > 0) {
    606     ui->Print("Retry attempt: %d\n", retry_count);
    607   }
    608   ui->SetEnableReboot(false);
    609   int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);
    610   ui->SetEnableReboot(true);
    611   ui->Print("\n");
    612 
    613   CloseArchive(zip);
    614   return result;
    615 }
    616 
    617 int install_package(const std::string& path, bool* wipe_cache, const std::string& install_file,
    618                     bool needs_mount, int retry_count) {
    619   CHECK(!path.empty());
    620   CHECK(!install_file.empty());
    621   CHECK(wipe_cache != nullptr);
    622 
    623   modified_flash = true;
    624   auto start = std::chrono::system_clock::now();
    625 
    626   int start_temperature = GetMaxValueFromThermalZone();
    627   int max_temperature = start_temperature;
    628 
    629   int result;
    630   std::vector<std::string> log_buffer;
    631   if (setup_install_mounts() != 0) {
    632     LOG(ERROR) << "failed to set up expected mounts for install; aborting";
    633     result = INSTALL_ERROR;
    634   } else {
    635     result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count,
    636                                     &max_temperature);
    637   }
    638 
    639   // Measure the time spent to apply OTA update in seconds.
    640   std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
    641   int time_total = static_cast<int>(duration.count());
    642 
    643   bool has_cache = volume_for_path("/cache") != nullptr;
    644   // Skip logging the uncrypt_status on devices without /cache.
    645   if (has_cache) {
    646     static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
    647     if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
    648       LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
    649     } else {
    650       std::string uncrypt_status;
    651       if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
    652         PLOG(WARNING) << "failed to read uncrypt status";
    653       } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
    654         LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
    655       } else {
    656         log_buffer.push_back(android::base::Trim(uncrypt_status));
    657       }
    658     }
    659   }
    660 
    661   // The first two lines need to be the package name and install result.
    662   std::vector<std::string> log_header = {
    663     path,
    664     result == INSTALL_SUCCESS ? "1" : "0",
    665     "time_total: " + std::to_string(time_total),
    666     "retry: " + std::to_string(retry_count),
    667   };
    668 
    669   int end_temperature = GetMaxValueFromThermalZone();
    670   max_temperature = std::max(end_temperature, max_temperature);
    671   if (start_temperature > 0) {
    672     log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
    673   }
    674   if (end_temperature > 0) {
    675     log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
    676   }
    677   if (max_temperature > 0) {
    678     log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
    679   }
    680 
    681   std::string log_content =
    682       android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n") + "\n";
    683   if (!android::base::WriteStringToFile(log_content, install_file)) {
    684     PLOG(ERROR) << "failed to write " << install_file;
    685   }
    686 
    687   // Write a copy into last_log.
    688   LOG(INFO) << log_content;
    689 
    690   return result;
    691 }
    692 
    693 bool verify_package(const unsigned char* package_data, size_t package_size) {
    694   static constexpr const char* PUBLIC_KEYS_FILE = "/res/keys";
    695   std::vector<Certificate> loadedKeys;
    696   if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) {
    697     LOG(ERROR) << "Failed to load keys";
    698     return false;
    699   }
    700   LOG(INFO) << loadedKeys.size() << " key(s) loaded from " << PUBLIC_KEYS_FILE;
    701 
    702   // Verify package.
    703   ui->Print("Verifying update package...\n");
    704   auto t0 = std::chrono::system_clock::now();
    705   int err = verify_file(package_data, package_size, loadedKeys,
    706                         std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
    707   std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
    708   ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
    709   if (err != VERIFY_SUCCESS) {
    710     LOG(ERROR) << "Signature verification failed";
    711     LOG(ERROR) << "error: " << kZipVerificationFailure;
    712     return false;
    713   }
    714   return true;
    715 }
    716