diff options
| author | Alessandro Astone <ales.astone@gmail.com> | 2020-03-17 23:06:52 +0100 |
|---|---|---|
| committer | Ćukasz Patron <priv.luk@gmail.com> | 2020-11-01 21:01:53 +0100 |
| commit | 878cc2d23ba26c8ffd3496105a91ab838b94c024 (patch) | |
| tree | 9d2b86b83a8577bbcf138dbe4a9c63fa96e6569c | |
| parent | 6fb8add96273a55a8c5b2c08884ad4d82c0bb422 (diff) | |
recovery: allow A/B updater to downgrader11.0
Change-Id: Iaa1fb7838fb958e69fb3104fef7743aafad12b1b
| -rw-r--r-- | install/include/install/install.h | 3 | ||||
| -rw-r--r-- | install/install.cpp | 24 | ||||
| -rw-r--r-- | install/wipe_device.cpp | 2 | ||||
| -rw-r--r-- | recovery.cpp | 9 |
4 files changed, 28 insertions, 10 deletions
diff --git a/install/include/install/install.h b/install/include/install/install.h index bef23e9c..aaa6036d 100644 --- a/install/include/install/install.h +++ b/install/include/install/install.h @@ -62,7 +62,8 @@ bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::st // Checks if the metadata in the OTA package has expected values. Mandatory checks: ota-type, // pre-device and serial number (if presents). A/B OTA specific checks: pre-build version, // fingerprint, timestamp. -bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type); +bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type, + RecoveryUI* ui); // Ensures the path to the update package is mounted. Also set the |should_use_fuse| to true if the // package stays on a removable media. diff --git a/install/install.cpp b/install/install.cpp index 59955e1f..85708b06 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -61,6 +61,7 @@ using namespace std::chrono_literals; bool ask_to_continue_unverified(Device* device); +bool ask_to_continue_downgrade(Device* device); static constexpr int kRecoveryApiVersion = 3; // We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed @@ -141,7 +142,8 @@ static void ReadSourceTargetBuild(const std::map<std::string, std::string>& meta // Checks the build version, fingerprint and timestamp in the metadata of the A/B package. // Downgrading is not allowed unless explicitly enabled in the package and only for // incremental packages. -static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& metadata) { +static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& metadata, + RecoveryUI* ui) { // Incremental updates should match the current build. auto device_pre_build = android::base::GetProperty("ro.build.version.incremental", ""); auto pkg_pre_build = get_value(metadata, "pre-build-incremental"); @@ -160,6 +162,7 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& me } // Check for downgrade version. + bool undeclared_downgrade = false; int64_t build_timestamp = android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max()); int64_t pkg_post_timestamp = 0; @@ -174,18 +177,23 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& me "newer than timestamp " << build_timestamp << " but package has timestamp " << pkg_post_timestamp << " and downgrade not allowed."; - return false; - } - if (pkg_pre_build_fingerprint.empty()) { + undeclared_downgrade = true; + } else if (pkg_pre_build_fingerprint.empty()) { LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed."; - return false; + undeclared_downgrade = true; } } + if (undeclared_downgrade && + !(ui->IsTextVisible() && ask_to_continue_downgrade(ui->GetDevice()))) { + return false; + } + return true; } -bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type) { +bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type, + RecoveryUI* ui) { auto package_ota_type = get_value(metadata, "ota-type"); auto expected_ota_type = OtaTypeToString(ota_type); if (ota_type != OtaType::AB && ota_type != OtaType::BRICK) { @@ -235,7 +243,7 @@ bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, Ot } if (ota_type == OtaType::AB) { - return CheckAbSpecificMetadata(metadata); + return CheckAbSpecificMetadata(metadata, ui); } return true; @@ -354,7 +362,7 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, // Package does not declare itself as an A/B package, but device only supports A/B; // still calls CheckPackageMetadata to get a meaningful error message. if (package_is_ab || device_only_supports_ab) { - if (!CheckPackageMetadata(metadata, OtaType::AB)) { + if (!CheckPackageMetadata(metadata, OtaType::AB, ui)) { log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure)); return INSTALL_ERROR; } diff --git a/install/wipe_device.cpp b/install/wipe_device.cpp index 89d5d31a..8422e54f 100644 --- a/install/wipe_device.cpp +++ b/install/wipe_device.cpp @@ -164,7 +164,7 @@ static bool CheckWipePackage(Package* wipe_package, RecoveryUI* ui) { return false; } - return CheckPackageMetadata(metadata, OtaType::BRICK); + return CheckPackageMetadata(metadata, OtaType::BRICK, ui); } bool WipeAbDevice(Device* device, size_t wipe_package_size) { diff --git a/recovery.cpp b/recovery.cpp index 28064ecc..3738ecc4 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -178,6 +178,15 @@ bool ask_to_continue_unverified(Device* device) { } } +bool ask_to_continue_downgrade(Device* device) { + if (get_build_type() == "user") { + return false; + } else { + device->GetUI()->SetProgressType(RecoveryUI::EMPTY); + return yes_no(device, "This package will downgrade your system", "Install anyway?"); + } +} + static bool ask_to_wipe_data(Device* device) { std::vector<std::string> headers{ "Format user data?", "This includes internal storage.", "THIS CANNOT BE UNDONE!" }; std::vector<std::string> items{ " Cancel", " Format data" }; |
