diff options
Diffstat (limited to '')
-rw-r--r-- | install.cpp | 161 |
1 files changed, 82 insertions, 79 deletions
diff --git a/install.cpp b/install.cpp index e144d9b29..919f241a2 100644 --- a/install.cpp +++ b/install.cpp @@ -31,19 +31,18 @@ #include <vector> #include <android-base/file.h> +#include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/properties.h> +#include <ziparchive/zip_archive.h> #include "common.h" #include "error_code.h" #include "install.h" #include "minui/minui.h" -#include "minzip/SysUtil.h" -#include "minzip/Zip.h" -#include "mtdutils/mounts.h" -#include "mtdutils/mtdutils.h" +#include "otautil/SysUtil.h" #include "roots.h" #include "ui.h" #include "verifier.h" @@ -64,8 +63,8 @@ static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4; static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1; // This function parses and returns the build.version.incremental -static int parse_build_number(std::string str) { - size_t pos = str.find("="); +static int parse_build_number(const std::string& str) { + size_t pos = str.find('='); if (pos != std::string::npos) { std::string num_string = android::base::Trim(str.substr(pos+1)); int build_number; @@ -74,27 +73,33 @@ static int parse_build_number(std::string str) { } } - LOGE("Failed to parse build number in %s.\n", str.c_str()); + LOG(ERROR) << "Failed to parse build number in " << str; return -1; } -bool read_metadata_from_package(ZipArchive* zip, std::string* meta_data) { - const ZipEntry* meta_entry = mzFindZipEntry(zip, METADATA_PATH); - if (meta_entry == nullptr) { - LOGE("Failed to find %s in update package.\n", METADATA_PATH); +bool read_metadata_from_package(ZipArchiveHandle zip, std::string* meta_data) { + ZipString metadata_path(METADATA_PATH); + ZipEntry meta_entry; + if (meta_data == nullptr) { + LOG(ERROR) << "string* meta_data can't be nullptr"; + return false; + } + if (FindEntry(zip, metadata_path, &meta_entry) != 0) { + LOG(ERROR) << "Failed to find " << METADATA_PATH << " in update package"; return false; } - meta_data->resize(meta_entry->uncompLen, '\0'); - if (!mzReadZipEntry(zip, meta_entry, &(*meta_data)[0], meta_entry->uncompLen)) { - LOGE("Failed to read metadata in update package.\n"); + meta_data->resize(meta_entry.uncompressed_length, '\0'); + if (ExtractToMemory(zip, &meta_entry, reinterpret_cast<uint8_t*>(&(*meta_data)[0]), + meta_entry.uncompressed_length) != 0) { + LOG(ERROR) << "Failed to read metadata in update package"; return false; } return true; } // Read the build.version.incremental of src/tgt from the metadata and log it to last_install. -static void read_source_target_build(ZipArchive* zip, std::vector<std::string>& log_buffer) { +static void read_source_target_build(ZipArchiveHandle zip, std::vector<std::string>& log_buffer) { std::string meta_data; if (!read_metadata_from_package(zip, &meta_data)) { return; @@ -126,7 +131,7 @@ static void read_source_target_build(ZipArchive* zip, std::vector<std::string>& // is the file descriptor the child process should use to report back the // progress of the update. static int -update_binary_command(const char* path, ZipArchive* zip, int retry_count, +update_binary_command(const char* path, ZipArchiveHandle zip, int retry_count, int status_fd, std::vector<std::string>* cmd); #ifdef AB_OTA_UPDATER @@ -134,7 +139,7 @@ update_binary_command(const char* path, ZipArchive* zip, int retry_count, // Parses the metadata of the OTA package in |zip| and checks whether we are // allowed to accept this A/B package. Downgrading is not allowed unless // explicitly enabled in the package and only for incremental packages. -static int check_newer_ab_build(ZipArchive* zip) +static int check_newer_ab_build(ZipArchiveHandle zip) { std::string metadata_str; if (!read_metadata_from_package(zip, &metadata_str)) { @@ -152,8 +157,7 @@ static int check_newer_ab_build(ZipArchive* zip) property_get("ro.product.device", value, ""); const std::string& pkg_device = metadata["pre-device"]; if (pkg_device != value || pkg_device.empty()) { - LOGE("Package is for product %s but expected %s\n", - pkg_device.c_str(), value); + LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << value; return INSTALL_ERROR; } @@ -162,12 +166,12 @@ static int check_newer_ab_build(ZipArchive* zip) property_get("ro.serialno", value, ""); const std::string& pkg_serial_no = metadata["serialno"]; if (!pkg_serial_no.empty() && pkg_serial_no != value) { - LOGE("Package is for serial %s\n", pkg_serial_no.c_str()); + LOG(ERROR) << "Package is for serial " << pkg_serial_no; return INSTALL_ERROR; } if (metadata["ota-type"] != "AB") { - LOGE("Package is not A/B\n"); + LOG(ERROR) << "Package is not A/B"; return INSTALL_ERROR; } @@ -175,39 +179,36 @@ static int check_newer_ab_build(ZipArchive* zip) property_get("ro.build.version.incremental", value, ""); const std::string& pkg_pre_build = metadata["pre-build-incremental"]; if (!pkg_pre_build.empty() && pkg_pre_build != value) { - LOGE("Package is for source build %s but expected %s\n", - pkg_pre_build.c_str(), value); + LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected " << value; return INSTALL_ERROR; } property_get("ro.build.fingerprint", value, ""); const std::string& pkg_pre_build_fingerprint = metadata["pre-build"]; if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != value) { - LOGE("Package is for source build %s but expected %s\n", - pkg_pre_build_fingerprint.c_str(), value); + LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint + << " but expected " << value; return INSTALL_ERROR; } // Check for downgrade version. - int64_t build_timestampt = property_get_int64( + int64_t build_timestamp = property_get_int64( "ro.build.date.utc", std::numeric_limits<int64_t>::max()); - int64_t pkg_post_timespampt = 0; + int64_t pkg_post_timestamp = 0; // We allow to full update to the same version we are running, in case there // is a problem with the current copy of that version. if (metadata["post-timestamp"].empty() || !android::base::ParseInt(metadata["post-timestamp"].c_str(), - &pkg_post_timespampt) || - pkg_post_timespampt < build_timestampt) { + &pkg_post_timestamp) || + pkg_post_timestamp < build_timestamp) { if (metadata["ota-downgrade"] != "yes") { - LOGE("Update package is older than the current build, expected a " - "build newer than timestamp %" PRIu64 " but package has " - "timestamp %" PRIu64 " and downgrade not allowed.\n", - build_timestampt, pkg_post_timespampt); + LOG(ERROR) << "Update package is older than the current build, expected a build " + "newer than timestamp " << build_timestamp << " but package has " + "timestamp " << pkg_post_timestamp << " and downgrade not allowed."; return INSTALL_ERROR; } if (pkg_pre_build_fingerprint.empty()) { - LOGE("Downgrade package must have a pre-build version set, not " - "allowed.\n"); + LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed."; return INSTALL_ERROR; } } @@ -216,7 +217,7 @@ static int check_newer_ab_build(ZipArchive* zip) } static int -update_binary_command(const char* path, ZipArchive* zip, int retry_count, +update_binary_command(const char* path, ZipArchiveHandle zip, int retry_count, int status_fd, std::vector<std::string>* cmd) { int ret = check_newer_ab_build(zip); @@ -226,26 +227,27 @@ update_binary_command(const char* path, ZipArchive* zip, int retry_count, // For A/B updates we extract the payload properties to a buffer and obtain // the RAW payload offset in the zip file. - const ZipEntry* properties_entry = - mzFindZipEntry(zip, AB_OTA_PAYLOAD_PROPERTIES); - if (!properties_entry) { - LOGE("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES); + ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES); + ZipEntry properties_entry; + if (FindEntry(zip, property_name, &properties_entry) != 0) { + LOG(ERROR) << "Can't find " << AB_OTA_PAYLOAD_PROPERTIES; return INSTALL_CORRUPT; } - std::vector<unsigned char> payload_properties( - mzGetZipEntryUncompLen(properties_entry)); - if (!mzExtractZipEntryToBuffer(zip, properties_entry, - payload_properties.data())) { - LOGE("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES); + std::vector<uint8_t> payload_properties( + properties_entry.uncompressed_length); + if (ExtractToMemory(zip, &properties_entry, payload_properties.data(), + properties_entry.uncompressed_length) != 0) { + LOG(ERROR) << "Can't extract " << AB_OTA_PAYLOAD_PROPERTIES; return INSTALL_CORRUPT; } - const ZipEntry* payload_entry = mzFindZipEntry(zip, AB_OTA_PAYLOAD); - if (!payload_entry) { - LOGE("Can't find %s\n", AB_OTA_PAYLOAD); + ZipString payload_name(AB_OTA_PAYLOAD); + ZipEntry payload_entry; + if (FindEntry(zip, payload_name, &payload_entry) != 0) { + LOG(ERROR) << "Can't find " << AB_OTA_PAYLOAD; return INSTALL_CORRUPT; } - long payload_offset = mzGetZipEntryOffset(payload_entry); + long payload_offset = payload_entry.offset; *cmd = { "/sbin/update_engine_sideload", android::base::StringPrintf("--payload=file://%s", path), @@ -260,13 +262,13 @@ update_binary_command(const char* path, ZipArchive* zip, int retry_count, #else // !AB_OTA_UPDATER static int -update_binary_command(const char* path, ZipArchive* zip, int retry_count, +update_binary_command(const char* path, ZipArchiveHandle zip, int retry_count, int status_fd, std::vector<std::string>* cmd) { // On traditional updates we extract the update binary from the package. - const ZipEntry* binary_entry = - mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME); - if (binary_entry == NULL) { + ZipString binary_name(ASSUMED_UPDATE_BINARY_NAME); + ZipEntry binary_entry; + if (FindEntry(zip, binary_name, &binary_entry) != 0) { return INSTALL_CORRUPT; } @@ -274,14 +276,15 @@ update_binary_command(const char* path, ZipArchive* zip, int retry_count, unlink(binary); int fd = creat(binary, 0755); if (fd < 0) { - LOGE("Can't make %s\n", binary); + PLOG(ERROR) << "Can't make " << binary; return INSTALL_ERROR; } - bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd); + int error = ExtractEntryToFile(zip, &binary_entry, fd); close(fd); - if (!ok) { - LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME); + if (error != 0) { + LOG(ERROR) << "Can't copy " << ASSUMED_UPDATE_BINARY_NAME + << " : " << ErrorCodeString(error); return INSTALL_ERROR; } @@ -299,7 +302,7 @@ update_binary_command(const char* path, ZipArchive* zip, int retry_count, // If the package contains an update binary, extract it and run it. static int -try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache, +try_update_binary(const char* path, ZipArchiveHandle zip, bool* wipe_cache, std::vector<std::string>& log_buffer, int retry_count) { read_source_target_build(zip, log_buffer); @@ -309,7 +312,6 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache, std::vector<std::string> args; int ret = update_binary_command(path, zip, retry_count, pipefd[1], &args); - mzCloseZipArchive(zip); if (ret) { close(pipefd[0]); close(pipefd[1]); @@ -377,7 +379,7 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache, if (pid == -1) { close(pipefd[0]); close(pipefd[1]); - LOGE("Failed to fork update binary: %s\n", strerror(errno)); + PLOG(ERROR) << "Failed to fork update binary"; return INSTALL_ERROR; } @@ -435,7 +437,7 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache, // last_install later. log_buffer.push_back(std::string(strtok(NULL, "\n"))); } else { - LOGE("unknown command [%s]\n", command); + LOG(ERROR) << "unknown command [" << command << "]"; } } fclose(from_child); @@ -446,7 +448,7 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache, return INSTALL_RETRY; } if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status)); + LOG(ERROR) << "Error in " << path << " (Status " << WEXITSTATUS(status) << ")"; return INSTALL_ERROR; } @@ -462,7 +464,7 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount, // Give verification half the progress bar... ui->SetProgressType(RecoveryUI::DETERMINATE); ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); - LOGI("Update location: %s\n", path); + LOG(INFO) << "Update location: " << path; // Map the update package into memory. ui->Print("Opening update package...\n"); @@ -477,7 +479,7 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount, MemMapping map; if (sysMapFile(path, &map) != 0) { - LOGE("failed to map file\n"); + LOG(ERROR) << "failed to map file"; return INSTALL_CORRUPT; } @@ -489,13 +491,14 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount, } // Try to open the package. - ZipArchive zip; - int err = mzOpenZipArchive(map.addr, map.length, &zip); + ZipArchiveHandle zip; + int err = OpenArchiveFromMemory(map.addr, map.length, path, &zip); if (err != 0) { - LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); + LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err); log_buffer.push_back(android::base::StringPrintf("error: %d", kZipOpenFailure)); sysReleaseMap(&map); + CloseArchive(zip); return INSTALL_CORRUPT; } @@ -505,12 +508,12 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount, ui->Print("Retry attempt: %d\n", retry_count); } ui->SetEnableReboot(false); - int result = try_update_binary(path, &zip, wipe_cache, log_buffer, retry_count); + int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count); ui->SetEnableReboot(true); ui->Print("\n"); sysReleaseMap(&map); - + CloseArchive(zip); return result; } @@ -524,7 +527,7 @@ install_package(const char* path, bool* wipe_cache, const char* install_file, int result; std::vector<std::string> log_buffer; if (setup_install_mounts() != 0) { - LOGE("failed to set up expected mounts for install; aborting\n"); + LOG(ERROR) << "failed to set up expected mounts for install; aborting"; result = INSTALL_ERROR; } else { result = really_install_package(path, wipe_cache, needs_mount, log_buffer, retry_count); @@ -535,13 +538,13 @@ install_package(const char* path, bool* wipe_cache, const char* install_file, int time_total = static_cast<int>(duration.count()); if (ensure_path_mounted(UNCRYPT_STATUS) != 0) { - LOGW("Can't mount %s\n", UNCRYPT_STATUS); + LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS; } else { std::string uncrypt_status; if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) { - LOGW("failed to read uncrypt status: %s\n", strerror(errno)); + PLOG(WARNING) << "failed to read uncrypt status"; } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) { - LOGW("corrupted uncrypt_status: %s: %s\n", uncrypt_status.c_str(), strerror(errno)); + LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status; } else { log_buffer.push_back(android::base::Trim(uncrypt_status)); } @@ -557,11 +560,11 @@ install_package(const char* path, bool* wipe_cache, const char* install_file, std::string log_content = android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n"); if (!android::base::WriteStringToFile(log_content, install_file)) { - LOGE("failed to write %s: %s\n", install_file, strerror(errno)); + PLOG(ERROR) << "failed to write " << install_file; } // Write a copy into last_log. - LOGI("%s\n", log_content.c_str()); + LOG(INFO) << log_content; return result; } @@ -569,10 +572,10 @@ install_package(const char* path, bool* wipe_cache, const char* install_file, bool verify_package(const unsigned char* package_data, size_t package_size) { std::vector<Certificate> loadedKeys; if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) { - LOGE("Failed to load keys\n"); + LOG(ERROR) << "Failed to load keys"; return false; } - LOGI("%zu key(s) loaded from %s\n", loadedKeys.size(), PUBLIC_KEYS_FILE); + LOG(INFO) << loadedKeys.size() << " key(s) loaded from " << PUBLIC_KEYS_FILE; // Verify package. ui->Print("Verifying update package...\n"); @@ -581,8 +584,8 @@ bool verify_package(const unsigned char* package_data, size_t package_size) { std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0; ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err); if (err != VERIFY_SUCCESS) { - LOGE("Signature verification failed\n"); - LOGE("error: %d\n", kZipVerificationFailure); + LOG(ERROR) << "Signature verification failed"; + LOG(ERROR) << "error: " << kZipVerificationFailure; return false; } return true; |