diff options
-rw-r--r-- | install/adb_install.cpp | 24 | ||||
-rw-r--r-- | install/fuse_sdcard_install.cpp | 10 | ||||
-rw-r--r-- | install/include/install/adb_install.h | 3 | ||||
-rw-r--r-- | install/include/install/fuse_sdcard_install.h | 3 | ||||
-rw-r--r-- | install/include/install/install.h | 3 | ||||
-rw-r--r-- | install/install.cpp | 10 | ||||
-rw-r--r-- | recovery.cpp | 20 |
7 files changed, 53 insertions, 20 deletions
diff --git a/install/adb_install.cpp b/install/adb_install.cpp index 84711d32..ad4be382 100644 --- a/install/adb_install.cpp +++ b/install/adb_install.cpp @@ -90,7 +90,11 @@ static bool WriteStatusToFd(MinadbdCommandStatus status, int fd) { // 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 @@ static auto AdbInstallPackageHandler(RecoveryUI* ui, int* result) { } } 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 @@ static void CreateMinadbdServiceAndExecuteCommands( 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 @@ int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot 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 @@ int ApplyFromAdb(Device* device, bool rescue_mode, Device::BuiltinAction* reboot 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 e528e483..4d324c25 100644 --- a/install/fuse_sdcard_install.cpp +++ b/install/fuse_sdcard_install.cpp @@ -136,7 +136,8 @@ static bool StartSdcardFuse(const std::string& path) { 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 @@ int ApplyFromSdcard(Device* device, RecoveryUI* ui) { } } - 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 3a0a8174..4c7b1ab7 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 d9214ca3..7f475357 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 c0a8f1f4..fe4c87ea 100644 --- a/install/include/install/install.h +++ b/install/include/install/install.h @@ -36,6 +36,7 @@ enum InstallResult { INSTALL_RETRY, INSTALL_KEY_INTERRUPTED, INSTALL_REBOOT, + INSTALL_UNVERIFIED, }; enum class OtaType { @@ -48,7 +49,7 @@ enum class OtaType { // 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 e2d47009..fd6d3f72 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -573,7 +573,7 @@ bool verify_package_compatibility(ZipArchiveHandle package_zip) { 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 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo } // 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 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo } 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 @@ int install_package(const std::string& path, bool should_wipe_cache, bool needs_ } 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; } diff --git a/recovery.cpp b/recovery.cpp index fdd72bfd..99737267 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -177,6 +177,15 @@ static bool yes_no(Device* device, const char* question1, const char* question2) return (chosen_item == 1); } +static bool ask_to_continue_unverified_fn(Device* device) { + if (get_build_type() == "user") { + return false; + } else { + ui->SetProgressType(RecoveryUI::EMPTY); + return yes_no(device, "Signature verification failed", "Install anyway?"); + } +} + static bool ask_to_wipe_data(Device* device) { std::vector<std::string> headers{ "Wipe all user data?", " THIS CAN NOT BE UNDONE!" }; std::vector<std::string> items{ " Cancel", " Factory data reset" }; @@ -574,10 +583,11 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { ui->ShowText(false); status = ApplyFromAdb(device, true /* rescue_mode */, &reboot_action); } else if (chosen_action == Device::APPLY_ADB_SIDELOAD) { - status = ApplyFromAdb(device, false /* rescue_mode */, &reboot_action); + status = ApplyFromAdb(device, false /* rescue_mode */, &reboot_action, + ask_to_continue_unverified_fn); } else { adb = false; - status = ApplyFromSdcard(device, ui); + status = ApplyFromSdcard(device, ui, ask_to_continue_unverified_fn); } ui->Print("\nInstall from %s completed with status %d.\n", adb ? "ADB" : "SD card", status); @@ -900,7 +910,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri set_retry_bootloader_message(retry_count + 1, args); } - status = install_package(update_package, should_wipe_cache, true, retry_count, ui); + status = install_package(update_package, should_wipe_cache, true, retry_count, + true /* verify */, ui); if (status != INSTALL_SUCCESS) { ui->Print("Installation aborted.\n"); @@ -965,7 +976,8 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri if (!sideload_auto_reboot) { ui->ShowText(true); } - status = ApplyFromAdb(device, false /* rescue_mode */, &next_action); + status = ApplyFromAdb(device, false /* rescue_mode */, &next_action, + !sideload_auto_reboot ? ask_to_continue_unverified_fn : nullptr); ui->Print("\nInstall from ADB complete (status: %d).\n", status); if (sideload_auto_reboot) { status = INSTALL_REBOOT; |