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