Skip to content

Commit f4a2bb1

Browse files
aleastomikeNG
authored andcommitted
recovery: allow A/B updater to downgrade
Change-Id: Iaa1fb7838fb958e69fb3104fef7743aafad12b1b
1 parent 974139a commit f4a2bb1

File tree

4 files changed

+28
-10
lines changed

4 files changed

+28
-10
lines changed

install/include/install/install.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::st
6464
// Checks if the metadata in the OTA package has expected values. Mandatory checks: ota-type,
6565
// pre-device and serial number (if presents). A/B OTA specific checks: pre-build version,
6666
// fingerprint, timestamp.
67-
bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type);
67+
bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type,
68+
RecoveryUI* ui);
6869

6970
// Ensures the path to the update package is mounted. Also set the |should_use_fuse| to true if the
7071
// package stays on a removable media.

install/install.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
using namespace std::chrono_literals;
6464

6565
bool ask_to_continue_unverified(Device* device);
66+
bool ask_to_continue_downgrade(Device* device);
6667

6768
static constexpr int kRecoveryApiVersion = 3;
6869
// 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
150151
// Checks the build version, fingerprint and timestamp in the metadata of the A/B package.
151152
// Downgrading is not allowed unless explicitly enabled in the package and only for
152153
// incremental packages.
153-
static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& metadata) {
154+
static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& metadata,
155+
RecoveryUI* ui) {
154156
// Incremental updates should match the current build.
155157
auto device_pre_build = android::base::GetProperty("ro.build.version.incremental", "");
156158
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
170172
}
171173

172174
// Check for downgrade version.
175+
bool undeclared_downgrade = false;
173176
int64_t build_timestamp =
174177
android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
175178
int64_t pkg_post_timestamp = 0;
@@ -184,11 +187,10 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& me
184187
"newer than timestamp "
185188
<< build_timestamp << " but package has timestamp " << pkg_post_timestamp
186189
<< " and downgrade not allowed.";
187-
return false;
188-
}
189-
if (pkg_pre_build_fingerprint.empty()) {
190+
undeclared_downgrade = true;
191+
} else if (pkg_pre_build_fingerprint.empty()) {
190192
LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
191-
return false;
193+
undeclared_downgrade = true;
192194
}
193195
}
194196
const auto post_build = get_value(metadata, "post-build");
@@ -203,10 +205,16 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& me
203205
}
204206
}
205207

208+
if (undeclared_downgrade &&
209+
!(ui->IsTextVisible() && ask_to_continue_downgrade(ui->GetDevice()))) {
210+
return false;
211+
}
212+
206213
return true;
207214
}
208215

209-
bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type) {
216+
bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type,
217+
RecoveryUI* ui) {
210218
auto package_ota_type = get_value(metadata, "ota-type");
211219
auto expected_ota_type = OtaTypeToString(ota_type);
212220
if (ota_type != OtaType::AB && ota_type != OtaType::BRICK) {
@@ -263,7 +271,7 @@ bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, Ot
263271
}
264272

265273
if (ota_type == OtaType::AB) {
266-
return CheckAbSpecificMetadata(metadata);
274+
return CheckAbSpecificMetadata(metadata, ui);
267275
}
268276

269277
return true;
@@ -427,7 +435,7 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
427435
// Package does not declare itself as an A/B package, but device only supports A/B;
428436
// still calls CheckPackageMetadata to get a meaningful error message.
429437
if (package_is_ab || device_only_supports_ab) {
430-
if (!CheckPackageMetadata(metadata, OtaType::AB)) {
438+
if (!CheckPackageMetadata(metadata, OtaType::AB, ui)) {
431439
log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
432440
return INSTALL_ERROR;
433441
}

install/wipe_device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static bool CheckWipePackage(Package* wipe_package, RecoveryUI* ui) {
169169
return false;
170170
}
171171

172-
return CheckPackageMetadata(metadata, OtaType::BRICK);
172+
return CheckPackageMetadata(metadata, OtaType::BRICK, ui);
173173
}
174174

175175
bool WipeAbDevice(Device* device, size_t wipe_package_size) {

recovery.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,15 @@ bool ask_to_continue_unverified(Device* device) {
174174
}
175175
}
176176

177+
bool ask_to_continue_downgrade(Device* device) {
178+
if (get_build_type() == "user") {
179+
return false;
180+
} else {
181+
device->GetUI()->SetProgressType(RecoveryUI::EMPTY);
182+
return yes_no(device, "This package will downgrade your system", "Install anyway?");
183+
}
184+
}
185+
177186
static bool ask_to_wipe_data(Device* device) {
178187
std::vector<std::string> headers{ "Format user data?", "This includes internal storage.", "THIS CANNOT BE UNDONE!" };
179188
std::vector<std::string> items{ " Cancel", " Format data" };

0 commit comments

Comments
 (0)