From c79f86ef94b50476213a4e3397afe9ac51d993ce Mon Sep 17 00:00:00 2001 From: mauronofrio Date: Mon, 18 May 2020 16:08:12 -0400 Subject: [PATCH] installcommand: port https://gerrit.twrp.me/c/android_bootable_recovery/+/1680 to install/installcommand.cpp Change-Id: I96384bbc92b202a8a5561229488052d488ca6bc1 --- install/installcommand.cpp | 22 ++- installcommand.cpp | 335 ------------------------------------- 2 files changed, 20 insertions(+), 337 deletions(-) delete mode 100644 installcommand.cpp diff --git a/install/installcommand.cpp b/install/installcommand.cpp index f4210568..5e284727 100755 --- a/install/installcommand.cpp +++ b/install/installcommand.cpp @@ -121,12 +121,30 @@ static int check_newer_ab_build(ZipWrap* zip) } } char value[PROPERTY_VALUE_MAX]; + char propmodel[PROPERTY_VALUE_MAX]; + char propname[PROPERTY_VALUE_MAX]; property_get("ro.product.device", value, ""); + property_get("ro.product.model", propmodel, ""); + property_get("ro.product.name", propname, ""); const std::string& pkg_device = metadata["pre-device"]; - if (pkg_device != value || pkg_device.empty()) { + + std::vector assertResults = android::base::Split(pkg_device, ","); + + bool deviceExists = false; + + for(const std::string& deviceAssert : assertResults) + { + std::string assertName = android::base::Trim(deviceAssert); + if ((assertName == value || assertName == propmodel || assertName == propname ) && !assertName.empty()) { + deviceExists = true; + break; + } + } + + if (!deviceExists) { printf("Package is for product %s but expected %s\n", - pkg_device.c_str(), value); + pkg_device.c_str(), value); return INSTALL_ERROR; } diff --git a/installcommand.cpp b/installcommand.cpp deleted file mode 100644 index 2a67e826..00000000 --- a/installcommand.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#ifdef AB_OTA_UPDATER -#include -#include -#include -#include -#include -#endif -#include - -#include "common.h" -#include "installcommand.h" -#include "zipwrap.hpp" -#ifndef USE_MINZIP -#include -#include -#endif -#ifdef USE_OLD_VERIFIER -#include "verifier24/verifier.h" -#else -#include "verifier.h" -#endif - -#ifdef AB_OTA_UPDATER - -static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt"; -static constexpr const char* AB_OTA_PAYLOAD = "payload.bin"; -static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata"; - -// This function parses and returns the build.version.incremental -static int parse_build_number(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; - if (android::base::ParseInt(num_string.c_str(), &build_number, 0)) { - return build_number; - } - } - - printf("Failed to parse build number in %s.\n", str.c_str()); - return -1; -} - -bool read_metadata_from_package(ZipWrap* zip, std::string* meta_data) { - long size = zip->GetUncompressedSize(METADATA_PATH); - if (size <= 0) - return false; - - meta_data->resize(size, '\0'); - if (!zip->ExtractToBuffer(METADATA_PATH, reinterpret_cast(&(*meta_data)[0]))) { - printf("Failed to read metadata in update package.\n"); - return false; - } - return true; -} - -// Read the build.version.incremental of src/tgt from the metadata and log it to last_install. -void read_source_target_build(ZipWrap* zip/*, std::vector& log_buffer*/) { - std::string meta_data; - if (!read_metadata_from_package(zip, &meta_data)) { - return; - } - // Examples of the pre-build and post-build strings in metadata: - // pre-build-incremental=2943039 - // post-build-incremental=2951741 - std::vector lines = android::base::Split(meta_data, "\n"); - for (const std::string& line : lines) { - std::string str = android::base::Trim(line); - if (android::base::StartsWith(str, "pre-build-incremental")){ - int source_build = parse_build_number(str); - if (source_build != -1) { - printf("source_build: %d\n", source_build); - /*log_buffer.push_back(android::base::StringPrintf("source_build: %d", - source_build));*/ - } - } else if (android::base::StartsWith(str, "post-build-incremental")) { - int target_build = parse_build_number(str); - if (target_build != -1) { - printf("target_build: %d\n", target_build); - /*log_buffer.push_back(android::base::StringPrintf("target_build: %d", - target_build));*/ - } - } - } -} - -// 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(ZipWrap* zip) -{ - std::string metadata_str; - if (!read_metadata_from_package(zip, &metadata_str)) { - return INSTALL_CORRUPT; - } - std::map metadata; - for (const std::string& line : android::base::Split(metadata_str, "\n")) { - size_t eq = line.find('='); - if (eq != std::string::npos) { - metadata[line.substr(0, eq)] = line.substr(eq + 1); - } - } - char value[PROPERTY_VALUE_MAX]; - char propmodel[PROPERTY_VALUE_MAX]; - char propname[PROPERTY_VALUE_MAX]; - - property_get("ro.product.device", value, ""); - property_get("ro.product.model", propmodel, ""); - property_get("ro.product.name", propname, ""); - const std::string& pkg_device = metadata["pre-device"]; - - std::vector assertResults = android::base::Split(pkg_device, ","); - - bool deviceExists = false; - - for(const std::string& deviceAssert : assertResults) - { - std::string assertName = android::base::Trim(deviceAssert); - if ((assertName == value || assertName == propmodel || assertName == propname ) && !assertName.empty()) { - deviceExists = true; - break; - } - } - - if (!deviceExists) { - printf("Package is for product %s but expected %s\n", - pkg_device.c_str(), value); - return INSTALL_ERROR; - } - - // We allow the package to not have any serialno, but if it has a non-empty - // value it should match. - property_get("ro.serialno", value, ""); - const std::string& pkg_serial_no = metadata["serialno"]; - if (!pkg_serial_no.empty() && pkg_serial_no != value) { - printf("Package is for serial %s\n", pkg_serial_no.c_str()); - return INSTALL_ERROR; - } - - if (metadata["ota-type"] != "AB") { - printf("Package is not A/B\n"); - return INSTALL_ERROR; - } - - // Incremental updates should match the current build. - 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) { - printf("Package is for source build %s but expected %s\n", - pkg_pre_build.c_str(), 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) { - printf("Package is for source build %s but expected %s\n", - pkg_pre_build_fingerprint.c_str(), value); - return INSTALL_ERROR; - } - - return 0; -} - -int -abupdate_binary_command(const char* path, ZipWrap* zip, int retry_count __unused, - int status_fd, std::vector* cmd) -{ - read_source_target_build(zip); - int ret = check_newer_ab_build(zip); - if (ret) { - return ret; - } - - // For A/B updates we extract the payload properties to a buffer and obtain - // the RAW payload offset in the zip file. - if (!zip->EntryExists(AB_OTA_PAYLOAD_PROPERTIES)) { - printf("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES); - return INSTALL_CORRUPT; - } - std::vector payload_properties( - zip->GetUncompressedSize(AB_OTA_PAYLOAD_PROPERTIES)); - if (!zip->ExtractToBuffer(AB_OTA_PAYLOAD_PROPERTIES, payload_properties.data())) { - printf("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES); - return INSTALL_CORRUPT; - } - - if (!zip->EntryExists(AB_OTA_PAYLOAD)) { - printf("Can't find %s\n", AB_OTA_PAYLOAD); - return INSTALL_CORRUPT; - } - long payload_offset = zip->GetEntryOffset(AB_OTA_PAYLOAD); - *cmd = { - "/sbin/update_engine_sideload", - android::base::StringPrintf("--payload=file://%s", path), - android::base::StringPrintf("--offset=%ld", payload_offset), - "--headers=" + std::string(payload_properties.begin(), - payload_properties.end()), - android::base::StringPrintf("--status_fd=%d", status_fd), - }; - return INSTALL_SUCCESS; -} - -#else - -void read_source_target_build(ZipWrap* zip __unused /*, std::vector& log_buffer*/) {return;} - -int -abupdate_binary_command(__unused const char* path, __unused ZipWrap* zip, __unused int retry_count, - __unused int status_fd, __unused std::vector* cmd) -{ - printf("No support for AB OTA zips included\n"); - return INSTALL_CORRUPT; -} - -#endif - -int -update_binary_command(const char* path, int retry_count, - int status_fd, std::vector* cmd) -{ - char charfd[16]; - sprintf(charfd, "%i", status_fd); - cmd->push_back(TMP_UPDATER_BINARY_PATH); - cmd->push_back(EXPAND(RECOVERY_API_VERSION)); - cmd->push_back(charfd); - cmd->push_back(path); - /**cmd = { - TMP_UPDATER_BINARY_PATH, - EXPAND(RECOVERY_API_VERSION), // defined in Android.mk - charfd, - path, - };*/ - if (retry_count > 0) - cmd->push_back("retry"); - return 0; -} - -#ifdef USE_MINZIP -bool verify_package_compatibility(ZipWrap *package_zip) { - if (package_zip->EntryExists("compatibility.zip")) - printf("Cannot verify treble package compatibility, must build TWRP in Oreo tree or higher.\n"); - return true; -} -#else -// Verifes the compatibility info in a Treble-compatible package. Returns true directly if the -// entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA -// package. -bool verify_package_compatibility(ZipWrap *zw) { - ZipArchiveHandle package_zip = zw->GetZipArchiveHandle(); - printf("Verifying package compatibility...\n"); - - static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip"; - ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY); - ZipEntry compatibility_entry; - if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) { - printf("Package doesn't contain %s entry\n", COMPATIBILITY_ZIP_ENTRY); - return true; - } - - std::string zip_content(compatibility_entry.uncompressed_length, '\0'); - int32_t ret; - if ((ret = ExtractToMemory(package_zip, &compatibility_entry, - reinterpret_cast(&zip_content[0]), - compatibility_entry.uncompressed_length)) != 0) { - printf("Failed to read %s: %s\n", COMPATIBILITY_ZIP_ENTRY, ErrorCodeString(ret)); - return false; - } - - ZipArchiveHandle zip_handle; - ret = OpenArchiveFromMemory(static_cast(const_cast(zip_content.data())), - zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle); - if (ret != 0) { - printf("Failed to OpenArchiveFromMemory: %s\n", ErrorCodeString(ret)); - return false; - } - - // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents. - void* cookie; - ret = StartIteration(zip_handle, &cookie, nullptr, nullptr); - if (ret != 0) { - printf("Failed to start iterating zip entries: %s\n", ErrorCodeString(ret)); - CloseArchive(zip_handle); - return false; - } - std::unique_ptr guard(cookie, EndIteration); - - std::vector compatibility_info; - ZipEntry info_entry; - ZipString info_name; - while (Next(cookie, &info_entry, &info_name) == 0) { - std::string content(info_entry.uncompressed_length, '\0'); - int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast(&content[0]), - info_entry.uncompressed_length); - if (ret != 0) { - printf("Failed to read %s: %s\n", info_name.name, ErrorCodeString(ret)); - CloseArchive(zip_handle); - return false; - } - compatibility_info.emplace_back(std::move(content)); - } - CloseArchive(zip_handle); - - // VintfObjectRecovery::CheckCompatibility returns zero on success. TODO THIS CAUSES A WEIRD COMPILE ERROR - std::string err; - int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err); - if (result == 0) { - return true; - } - - printf("Failed to verify package compatibility (result %i): %s\n", result, err.c_str()); - return false; -} -#endif ->>>>>>> CHANGE (1913bf Make the twrp verify the pre-device among several props)