recovery: allow A/B updater to downgrade
Change-Id: Iaa1fb7838fb958e69fb3104fef7743aafad12b1b
This commit is contained in:
committed by
Michael Bestas
parent
2e2a7456ca
commit
c52be7e50a
@@ -64,7 +64,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,
|
// 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,
|
// pre-device and serial number (if presents). A/B OTA specific checks: pre-build version,
|
||||||
// fingerprint, timestamp.
|
// 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
|
// 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.
|
// package stays on a removable media.
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
bool ask_to_continue_unverified(Device* device);
|
bool ask_to_continue_unverified(Device* device);
|
||||||
|
bool ask_to_continue_downgrade(Device* device);
|
||||||
|
|
||||||
static constexpr int kRecoveryApiVersion = 3;
|
static constexpr int kRecoveryApiVersion = 3;
|
||||||
// We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed
|
// We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed
|
||||||
@@ -150,7 +151,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.
|
// 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
|
// Downgrading is not allowed unless explicitly enabled in the package and only for
|
||||||
// incremental packages.
|
// 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.
|
// Incremental updates should match the current build.
|
||||||
auto device_pre_build = android::base::GetProperty("ro.build.version.incremental", "");
|
auto device_pre_build = android::base::GetProperty("ro.build.version.incremental", "");
|
||||||
auto pkg_pre_build = get_value(metadata, "pre-build-incremental");
|
auto pkg_pre_build = get_value(metadata, "pre-build-incremental");
|
||||||
@@ -170,6 +172,7 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& me
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for downgrade version.
|
// Check for downgrade version.
|
||||||
|
bool undeclared_downgrade = false;
|
||||||
int64_t build_timestamp =
|
int64_t build_timestamp =
|
||||||
android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
|
android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
|
||||||
int64_t pkg_post_timestamp = 0;
|
int64_t pkg_post_timestamp = 0;
|
||||||
@@ -184,18 +187,23 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& me
|
|||||||
"newer than timestamp "
|
"newer than timestamp "
|
||||||
<< build_timestamp << " but package has timestamp " << pkg_post_timestamp
|
<< build_timestamp << " but package has timestamp " << pkg_post_timestamp
|
||||||
<< " and downgrade not allowed.";
|
<< " and downgrade not allowed.";
|
||||||
return false;
|
undeclared_downgrade = true;
|
||||||
}
|
} else if (pkg_pre_build_fingerprint.empty()) {
|
||||||
if (pkg_pre_build_fingerprint.empty()) {
|
|
||||||
LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
|
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;
|
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 package_ota_type = get_value(metadata, "ota-type");
|
||||||
auto expected_ota_type = OtaTypeToString(ota_type);
|
auto expected_ota_type = OtaTypeToString(ota_type);
|
||||||
if (ota_type != OtaType::AB && ota_type != OtaType::BRICK) {
|
if (ota_type != OtaType::AB && ota_type != OtaType::BRICK) {
|
||||||
@@ -252,7 +260,7 @@ bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, Ot
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ota_type == OtaType::AB) {
|
if (ota_type == OtaType::AB) {
|
||||||
return CheckAbSpecificMetadata(metadata);
|
return CheckAbSpecificMetadata(metadata, ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -416,7 +424,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;
|
// 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.
|
// still calls CheckPackageMetadata to get a meaningful error message.
|
||||||
if (package_is_ab || device_only_supports_ab) {
|
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));
|
log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
|
||||||
return INSTALL_ERROR;
|
return INSTALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ static bool CheckWipePackage(Package* wipe_package, RecoveryUI* ui) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CheckPackageMetadata(metadata, OtaType::BRICK);
|
return CheckPackageMetadata(metadata, OtaType::BRICK, ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WipeAbDevice(Device* device, size_t wipe_package_size) {
|
bool WipeAbDevice(Device* device, size_t wipe_package_size) {
|
||||||
|
|||||||
@@ -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) {
|
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> headers{ "Format user data?", "This includes internal storage.", "THIS CANNOT BE UNDONE!" };
|
||||||
std::vector<std::string> items{ " Cancel", " Format data" };
|
std::vector<std::string> items{ " Cancel", " Format data" };
|
||||||
|
|||||||
Reference in New Issue
Block a user