recovery: Allow bypassing signature verification on non-release builds
For non-release (userdebug, eng) builds, when signature verification
fails, ask the user whether they wish to install anyway.
Change-Id: I950ad455e6f698cabe348f0482eb64287cc88a08
diff --git a/install/adb_install.cpp b/install/adb_install.cpp
index 84711d3..ad4be38 100644
--- a/install/adb_install.cpp
+++ b/install/adb_install.cpp
@@ -90,7 +90,11 @@
// Installs the package from FUSE. Returns the installation result and whether it should continue
// waiting for new commands.
-static auto AdbInstallPackageHandler(RecoveryUI* ui, int* result) {
+static auto AdbInstallPackageHandler(
+ Device* device, int* result,
+ const std::function<bool(Device*)>& ask_to_continue_unverified_fn) {
+ RecoveryUI* ui = device->GetUI();
+
// How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long
// because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME
// will start to exist once the host connects and starts serving a package. Poll for its
@@ -111,7 +115,13 @@
}
}
ui->CancelWaitKey();
- *result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0, ui);
+
+ *result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0, true /* verify */, ui);
+ if (*result == INSTALL_UNVERIFIED && ask_to_continue_unverified_fn &&
+ ask_to_continue_unverified_fn(device)) {
+ *result =
+ install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0, false /* verify */, ui);
+ }
break;
}
@@ -347,7 +357,8 @@
signal(SIGPIPE, SIG_DFL);
}
-int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot_action) {
+int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot_action,
+ const std::function<bool(Device*)>& ask_to_continue_unverified_fn) {
// Save the usb state to restore after the sideload operation.
std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
// Clean up state and stop adbd.
@@ -356,11 +367,10 @@
return INSTALL_ERROR;
}
- RecoveryUI* ui = device->GetUI();
-
int install_result = INSTALL_ERROR;
std::map<MinadbdCommand, CommandFunction> command_map{
- { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, ui, &install_result) },
+ { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, device, &install_result,
+ ask_to_continue_unverified_fn) },
{ MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid,
&install_result, reboot_action) },
{ MinadbdCommand::kRebootBootloader,
@@ -374,6 +384,8 @@
std::bind(&AdbRebootHandler, MinadbdCommand::kRebootRescue, &install_result, reboot_action) },
};
+ RecoveryUI* ui = device->GetUI();
+
if (!rescue_mode) {
ui->Print(
"\n\nNow send the package you want to apply\n"
diff --git a/install/fuse_sdcard_install.cpp b/install/fuse_sdcard_install.cpp
index e528e48..4d324c2 100644
--- a/install/fuse_sdcard_install.cpp
+++ b/install/fuse_sdcard_install.cpp
@@ -136,7 +136,8 @@
return run_fuse_sideload(std::move(file_data_reader)) == 0;
}
-int ApplyFromSdcard(Device* device, RecoveryUI* ui) {
+int ApplyFromSdcard(Device* device, RecoveryUI* ui,
+ const std::function<bool(Device*)>& ask_to_continue_unverified_fn) {
if (ensure_path_mounted(SDCARD_ROOT) != 0) {
LOG(ERROR) << "\n-- Couldn't mount " << SDCARD_ROOT << ".\n";
return INSTALL_ERROR;
@@ -190,7 +191,12 @@
}
}
- result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0 /*retry_count*/, ui);
+ result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0 /*retry_count*/,
+ true /* verify */, ui);
+ if (result == INSTALL_UNVERIFIED && ask_to_continue_unverified_fn(device)) {
+ result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0 /*retry_count*/,
+ false /* verify */, ui);
+ }
break;
}
diff --git a/install/include/install/adb_install.h b/install/include/install/adb_install.h
index 3a0a817..4c7b1ab 100644
--- a/install/include/install/adb_install.h
+++ b/install/include/install/adb_install.h
@@ -21,4 +21,5 @@
// Applies a package via `adb sideload` or `adb rescue`. Returns the install result (in `enum
// InstallResult`). When a reboot has been requested, INSTALL_REBOOT will be the return value, with
// the reboot target set in reboot_action.
-int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot_action);
+int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot_action,
+ const std::function<bool(Device*)>& ask_to_continue_unverified = nullptr);
diff --git a/install/include/install/fuse_sdcard_install.h b/install/include/install/fuse_sdcard_install.h
index d9214ca..7f47535 100644
--- a/install/include/install/fuse_sdcard_install.h
+++ b/install/include/install/fuse_sdcard_install.h
@@ -19,4 +19,5 @@
#include "recovery_ui/device.h"
#include "recovery_ui/ui.h"
-int ApplyFromSdcard(Device* device, RecoveryUI* ui);
+int ApplyFromSdcard(Device* device, RecoveryUI* ui,
+ const std::function<bool(Device*)>& ask_to_continue_unverified_fn);
diff --git a/install/include/install/install.h b/install/include/install/install.h
index c0a8f1f..fe4c87e 100644
--- a/install/include/install/install.h
+++ b/install/include/install/install.h
@@ -36,6 +36,7 @@
INSTALL_RETRY,
INSTALL_KEY_INTERRUPTED,
INSTALL_REBOOT,
+ INSTALL_UNVERIFIED,
};
enum class OtaType {
@@ -48,7 +49,7 @@
// successful installation if |should_wipe_cache| is true or an updater command asks to wipe the
// cache.
int install_package(const std::string& package, bool should_wipe_cache, bool needs_mount,
- int retry_count, RecoveryUI* ui);
+ int retry_count, bool verify, RecoveryUI* ui);
// Verifies the package by ota keys. Returns true if the package is verified successfully,
// otherwise returns false.
diff --git a/install/install.cpp b/install/install.cpp
index e2d4700..fd6d3f7 100644
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -573,7 +573,7 @@
static int really_install_package(const std::string& path, bool* wipe_cache, bool needs_mount,
std::vector<std::string>* log_buffer, int retry_count,
- int* max_temperature, RecoveryUI* ui) {
+ bool verify, int* max_temperature, RecoveryUI* ui) {
ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
ui->Print("Finding update package...\n");
// Give verification half the progress bar...
@@ -600,9 +600,9 @@
}
// Verify package.
- if (!verify_package(package.get(), ui)) {
+ if (verify && !verify_package(package.get(), ui)) {
log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
- return INSTALL_CORRUPT;
+ return INSTALL_UNVERIFIED;
}
// Try to open the package.
@@ -633,7 +633,7 @@
}
int install_package(const std::string& path, bool should_wipe_cache, bool needs_mount,
- int retry_count, RecoveryUI* ui) {
+ int retry_count, bool verify, RecoveryUI* ui) {
CHECK(!path.empty());
auto start = std::chrono::system_clock::now();
@@ -649,7 +649,7 @@
} else {
bool updater_wipe_cache = false;
result = really_install_package(path, &updater_wipe_cache, needs_mount, &log_buffer,
- retry_count, &max_temperature, ui);
+ retry_count, verify, &max_temperature, ui);
should_wipe_cache = should_wipe_cache || updater_wipe_cache;
}