diff options
Diffstat (limited to '')
-rw-r--r-- | install/Android.bp | 78 | ||||
-rw-r--r-- | install/adb_install.cpp (renamed from adb_install.cpp) | 14 | ||||
-rw-r--r-- | install/asn1_decoder.cpp (renamed from asn1_decoder.cpp) | 4 | ||||
-rw-r--r-- | install/fuse_sdcard_install.cpp (renamed from fuse_sdcard_install.cpp) | 8 | ||||
-rw-r--r-- | install/include/install/adb_install.h (renamed from adb_install.h) | 7 | ||||
-rw-r--r-- | install/include/install/fuse_sdcard_install.h (renamed from fuse_sdcard_install.h) | 0 | ||||
-rw-r--r-- | install/include/install/install.h (renamed from install.h) | 12 | ||||
-rw-r--r-- | install/include/install/package.h (renamed from package.h) | 0 | ||||
-rw-r--r-- | install/include/install/verifier.h (renamed from verifier.h) | 45 | ||||
-rw-r--r-- | install/include/private/asn1_decoder.h (renamed from asn1_decoder.h) | 1 | ||||
-rw-r--r-- | install/include/private/setup_commands.h (renamed from private/install.h) | 0 | ||||
-rw-r--r-- | install/install.cpp (renamed from install.cpp) | 36 | ||||
-rw-r--r-- | install/package.cpp (renamed from package.cpp) | 2 | ||||
-rw-r--r-- | install/verifier.cpp (renamed from verifier.cpp) | 41 |
14 files changed, 162 insertions, 86 deletions
diff --git a/install/Android.bp b/install/Android.bp new file mode 100644 index 000000000..aa47990ae --- /dev/null +++ b/install/Android.bp @@ -0,0 +1,78 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_defaults { + name: "libinstall_defaults", + + defaults: [ + "recovery_defaults", + ], + + shared_libs: [ + "libbase", + "libbootloader_message", + "libcrypto", + "libext4_utils", + "libfs_mgr", + "libfusesideload", + "libhidl-gen-utils", + "libhidlbase", + "libhidltransport", + "liblog", + "libselinux", + "libtinyxml2", + "libutils", + "libz", + "libziparchive", + ], + + static_libs: [ + "libotautil", + + // external dependencies + "libvintf_recovery", + "libvintf", + "libfstab", + ], +} + +cc_library { + name: "libinstall", + recovery_available: true, + + defaults: [ + "libinstall_defaults", + ], + + srcs: [ + "adb_install.cpp", + "asn1_decoder.cpp", + "fuse_sdcard_install.cpp", + "install.cpp", + "package.cpp", + "verifier.cpp", + ], + + shared_libs: [ + "librecovery_ui", + ], + + export_include_dirs: [ + "include", + ], + + export_shared_lib_headers: [ + "librecovery_ui", + ], +} diff --git a/adb_install.cpp b/install/adb_install.cpp index 1d19fd3a1..5296ff608 100644 --- a/adb_install.cpp +++ b/install/adb_install.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "adb_install.h" +#include "install/adb_install.h" #include <errno.h> #include <fcntl.h> @@ -29,12 +29,16 @@ #include <android-base/logging.h> #include <android-base/properties.h> -#include "common.h" #include "fuse_sideload.h" -#include "install.h" +#include "install/install.h" #include "recovery_ui/ui.h" -int apply_from_adb(bool* wipe_cache) { +static bool SetUsbConfig(const std::string& state) { + android::base::SetProperty("sys.usb.config", state); + return android::base::WaitForProperty("sys.usb.state", state); +} + +int apply_from_adb(bool* wipe_cache, RecoveryUI* ui) { // 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. @@ -85,7 +89,7 @@ int apply_from_adb(bool* wipe_cache) { break; } } - result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, false, 0); + result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, false, 0, ui); break; } diff --git a/asn1_decoder.cpp b/install/asn1_decoder.cpp index 285214f16..2d81a6e13 100644 --- a/asn1_decoder.cpp +++ b/install/asn1_decoder.cpp @@ -14,9 +14,7 @@ * limitations under the License. */ -#include "asn1_decoder.h" - -#include <stdint.h> +#include "private/asn1_decoder.h" int asn1_context::peek_byte() const { if (length_ == 0) { diff --git a/fuse_sdcard_install.cpp b/install/fuse_sdcard_install.cpp index 1f385093f..dde289f80 100644 --- a/fuse_sdcard_install.cpp +++ b/install/fuse_sdcard_install.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "fuse_sdcard_install.h" +#include "install/fuse_sdcard_install.h" #include <dirent.h> #include <signal.h> @@ -35,8 +35,8 @@ #include "bootloader_message/bootloader_message.h" #include "fuse_provider.h" #include "fuse_sideload.h" -#include "install.h" -#include "roots.h" +#include "install/install.h" +#include "otautil/roots.h" static constexpr const char* SDCARD_ROOT = "/sdcard"; // How long (in seconds) we wait for the fuse-provided package file to @@ -184,7 +184,7 @@ int ApplyFromSdcard(Device* device, bool* wipe_cache, RecoveryUI* ui) { } } - result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, false, 0 /*retry_count*/); + result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, false, 0 /*retry_count*/, ui); break; } diff --git a/adb_install.h b/install/include/install/adb_install.h index cc3ca267b..dbc824501 100644 --- a/adb_install.h +++ b/install/include/install/adb_install.h @@ -14,9 +14,8 @@ * limitations under the License. */ -#ifndef _ADB_INSTALL_H -#define _ADB_INSTALL_H +#pragma once -int apply_from_adb(bool* wipe_cache); +#include <recovery_ui/ui.h> -#endif +int apply_from_adb(bool* wipe_cache, RecoveryUI* ui); diff --git a/fuse_sdcard_install.h b/install/include/install/fuse_sdcard_install.h index 345aea45b..345aea45b 100644 --- a/fuse_sdcard_install.h +++ b/install/include/install/fuse_sdcard_install.h diff --git a/install.h b/install/include/install/install.h index da8aa5e39..74fb3d170 100644 --- a/install.h +++ b/install/include/install/install.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef RECOVERY_INSTALL_H_ -#define RECOVERY_INSTALL_H_ +#pragma once #include <stddef.h> @@ -26,6 +25,7 @@ #include <ziparchive/zip_archive.h> #include "package.h" +#include "recovery_ui/ui.h" enum InstallResult { INSTALL_SUCCESS, @@ -45,12 +45,12 @@ enum class OtaType { // Installs the given update package. If INSTALL_SUCCESS is returned and *wipe_cache is true on // exit, caller should wipe the cache partition. -int install_package(const std::string& package, bool* wipe_cache, bool needs_mount, - int retry_count); +int install_package(const std::string& package, bool* wipe_cache, bool needs_mount, int retry_count, + RecoveryUI* ui); // Verifies the package by ota keys. Returns true if the package is verified successfully, // otherwise returns false. -bool verify_package(Package* package); +bool verify_package(Package* package, RecoveryUI* ui); // Reads meta data file of the package; parses each line in the format "key=value"; and writes the // result to |metadata|. Return true if succeed, otherwise return false. @@ -67,5 +67,3 @@ bool verify_package_compatibility(ZipArchiveHandle package_zip); // Mandatory checks: ota-type, pre-device and serial number(if presents) // AB OTA specific checks: pre-build version, fingerprint, timestamp. int CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type); - -#endif // RECOVERY_INSTALL_H_ diff --git a/package.h b/install/include/install/package.h index cd44d10be..cd44d10be 100644 --- a/package.h +++ b/install/include/install/package.h diff --git a/verifier.h b/install/include/install/verifier.h index 106b86b85..f9e947580 100644 --- a/verifier.h +++ b/install/include/install/verifier.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef _RECOVERY_VERIFIER_H -#define _RECOVERY_VERIFIER_H +#pragma once #include <stdint.h> @@ -44,25 +43,20 @@ struct ECKEYDeleter { }; struct Certificate { - typedef enum { - KEY_TYPE_RSA, - KEY_TYPE_EC, - } KeyType; - - Certificate(int hash_len_, - KeyType key_type_, - std::unique_ptr<RSA, RSADeleter>&& rsa_, - std::unique_ptr<EC_KEY, ECKEYDeleter>&& ec_) - : hash_len(hash_len_), - key_type(key_type_), - rsa(std::move(rsa_)), - ec(std::move(ec_)) {} - - // SHA_DIGEST_LENGTH (SHA-1) or SHA256_DIGEST_LENGTH (SHA-256) - int hash_len; - KeyType key_type; - std::unique_ptr<RSA, RSADeleter> rsa; - std::unique_ptr<EC_KEY, ECKEYDeleter> ec; + typedef enum { + KEY_TYPE_RSA, + KEY_TYPE_EC, + } KeyType; + + Certificate(int hash_len_, KeyType key_type_, std::unique_ptr<RSA, RSADeleter>&& rsa_, + std::unique_ptr<EC_KEY, ECKEYDeleter>&& ec_) + : hash_len(hash_len_), key_type(key_type_), rsa(std::move(rsa_)), ec(std::move(ec_)) {} + + // SHA_DIGEST_LENGTH (SHA-1) or SHA256_DIGEST_LENGTH (SHA-256) + int hash_len; + KeyType key_type; + std::unique_ptr<RSA, RSADeleter> rsa; + std::unique_ptr<EC_KEY, ECKEYDeleter> ec; }; class VerifierInterface { @@ -88,7 +82,8 @@ class VerifierInterface { // VERIFY_FAILURE (if any error is encountered or no key matches the signature). int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys); -// Checks that the RSA key has a modulus of 2048 bits long, and public exponent is 3 or 65537. +// Checks that the RSA key has a modulus of 2048 or 4096 bits long, and public exponent is 3 or +// 65537. bool CheckRSAKey(const std::unique_ptr<RSA, RSADeleter>& rsa); // Checks that the field size of the curve for the EC key is 256 bits. @@ -102,7 +97,5 @@ bool LoadCertificateFromBuffer(const std::vector<uint8_t>& pem_content, Certific // certificates. Returns an empty list if we fail to parse any of the entries. std::vector<Certificate> LoadKeysFromZipfile(const std::string& zip_name); -#define VERIFY_SUCCESS 0 -#define VERIFY_FAILURE 1 - -#endif /* _RECOVERY_VERIFIER_H */ +#define VERIFY_SUCCESS 0 +#define VERIFY_FAILURE 1 diff --git a/asn1_decoder.h b/install/include/private/asn1_decoder.h index 3e992115a..e5337d9c4 100644 --- a/asn1_decoder.h +++ b/install/include/private/asn1_decoder.h @@ -17,6 +17,7 @@ #ifndef ASN1_DECODER_H_ #define ASN1_DECODER_H_ +#include <stddef.h> #include <stdint.h> class asn1_context { diff --git a/private/install.h b/install/include/private/setup_commands.h index 7fdc741d6..7fdc741d6 100644 --- a/private/install.h +++ b/install/include/private/setup_commands.h diff --git a/install.cpp b/install/install.cpp index b7fb78878..a1124c361 100644 --- a/install.cpp +++ b/install/install.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "install.h" +#include "install/install.h" #include <ctype.h> #include <errno.h> @@ -46,19 +46,22 @@ #include <android-base/unique_fd.h> #include <vintf/VintfObjectRecovery.h> -#include "common.h" +#include "install/package.h" +#include "install/verifier.h" #include "otautil/error_code.h" #include "otautil/paths.h" +#include "otautil/roots.h" #include "otautil/sysutil.h" #include "otautil/thermalutil.h" -#include "package.h" -#include "private/install.h" +#include "private/setup_commands.h" #include "recovery_ui/ui.h" -#include "roots.h" -#include "verifier.h" using namespace std::chrono_literals; +static constexpr int kRecoveryApiVersion = 3; +// Assert the version defined in code and in Android.mk are consistent. +static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery API versions."); + // Default allocation of progress bar segments to operations static constexpr int VERIFICATION_PROGRESS_TIME = 60; static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25; @@ -323,7 +326,7 @@ static void log_max_temperature(int* max_temperature, const std::atomic<bool>& l // If the package contains an update binary, extract it and run it. static int try_update_binary(const std::string& package, ZipArchiveHandle zip, bool* wipe_cache, std::vector<std::string>* log_buffer, int retry_count, - int* max_temperature) { + int* max_temperature, RecoveryUI* ui) { std::map<std::string, std::string> metadata; if (!ReadMetadataFromPackage(zip, &metadata)) { LOG(ERROR) << "Failed to parse metadata in the zip file"; @@ -342,7 +345,9 @@ static int try_update_binary(const std::string& package, ZipArchiveHandle zip, b // The updater in child process writes to the pipe to communicate with recovery. android::base::unique_fd pipe_read, pipe_write; - if (!android::base::Pipe(&pipe_read, &pipe_write)) { + // Explicitly disable O_CLOEXEC using 0 as the flags (last) parameter to Pipe + // so that the child updater process will recieve a non-closed fd. + if (!android::base::Pipe(&pipe_read, &pipe_write, 0)) { PLOG(ERROR) << "Failed to create pipe for updater-recovery communication"; return INSTALL_CORRUPT; } @@ -567,7 +572,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) { + int* max_temperature, RecoveryUI* ui) { ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); ui->Print("Finding update package...\n"); // Give verification half the progress bar... @@ -594,7 +599,7 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo } // Verify package. - if (!verify_package(package.get())) { + if (!verify_package(package.get(), ui)) { log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure)); return INSTALL_CORRUPT; } @@ -618,18 +623,19 @@ static int really_install_package(const std::string& path, bool* wipe_cache, boo ui->Print("Retry attempt: %d\n", retry_count); } ui->SetEnableReboot(false); - int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature); + int result = + try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature, ui); ui->SetEnableReboot(true); ui->Print("\n"); return result; } -int install_package(const std::string& path, bool* wipe_cache, bool needs_mount, int retry_count) { +int install_package(const std::string& path, bool* wipe_cache, bool needs_mount, int retry_count, + RecoveryUI* ui) { CHECK(!path.empty()); CHECK(wipe_cache != nullptr); - modified_flash = true; auto start = std::chrono::system_clock::now(); int start_temperature = GetMaxValueFromThermalZone(); @@ -642,7 +648,7 @@ int install_package(const std::string& path, bool* wipe_cache, bool needs_mount, result = INSTALL_ERROR; } else { result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count, - &max_temperature); + &max_temperature, ui); } // Measure the time spent to apply OTA update in seconds. @@ -700,7 +706,7 @@ int install_package(const std::string& path, bool* wipe_cache, bool needs_mount, return result; } -bool verify_package(Package* package) { +bool verify_package(Package* package, RecoveryUI* ui) { static constexpr const char* CERTIFICATE_ZIP_FILE = "/system/etc/security/otacerts.zip"; std::vector<Certificate> loaded_keys = LoadKeysFromZipfile(CERTIFICATE_ZIP_FILE); if (loaded_keys.empty()) { diff --git a/package.cpp b/install/package.cpp index 6c7289f3f..4402f4855 100644 --- a/package.cpp +++ b/install/package.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "package.h" +#include "install/package.h" #include <string.h> #include <unistd.h> diff --git a/verifier.cpp b/install/verifier.cpp index 68a011e0d..6ba1d77c3 100644 --- a/verifier.cpp +++ b/install/verifier.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "verifier.h" +#include "install/verifier.h" #include <errno.h> #include <stdio.h> @@ -36,8 +36,8 @@ #include <openssl/rsa.h> #include <ziparchive/zip_archive.h> -#include "asn1_decoder.h" #include "otautil/print_sha1.h" +#include "private/asn1_decoder.h" /* * Simple version of PKCS#7 SignedData extraction. This extracts the @@ -82,10 +82,8 @@ static bool read_pkcs7(const uint8_t* pkcs7_der, size_t pkcs7_der_len, } std::unique_ptr<asn1_context> signed_data_seq(signed_data_app->asn1_sequence_get()); - if (signed_data_seq == nullptr || - !signed_data_seq->asn1_sequence_next() || - !signed_data_seq->asn1_sequence_next() || - !signed_data_seq->asn1_sequence_next() || + if (signed_data_seq == nullptr || !signed_data_seq->asn1_sequence_next() || + !signed_data_seq->asn1_sequence_next() || !signed_data_seq->asn1_sequence_next() || !signed_data_seq->asn1_constructed_skip_all()) { return false; } @@ -96,11 +94,8 @@ static bool read_pkcs7(const uint8_t* pkcs7_der, size_t pkcs7_der_len, } std::unique_ptr<asn1_context> sig_seq(sig_set->asn1_sequence_get()); - if (sig_seq == nullptr || - !sig_seq->asn1_sequence_next() || - !sig_seq->asn1_sequence_next() || - !sig_seq->asn1_sequence_next() || - !sig_seq->asn1_sequence_next()) { + if (sig_seq == nullptr || !sig_seq->asn1_sequence_next() || !sig_seq->asn1_sequence_next() || + !sig_seq->asn1_sequence_next() || !sig_seq->asn1_sequence_next()) { return false; } @@ -152,8 +147,8 @@ int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys << " bytes from end"; if (signature_start > comment_size) { - LOG(ERROR) << "signature start: " << signature_start << " is larger than comment size: " - << comment_size; + LOG(ERROR) << "signature start: " << signature_start + << " is larger than comment size: " << comment_size; return VERIFY_FAILURE; } @@ -189,8 +184,8 @@ int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys return VERIFY_FAILURE; } - for (size_t i = 4; i < eocd_size-3; ++i) { - if (eocd[i] == 0x50 && eocd[i+1] == 0x4b && eocd[i+2] == 0x05 && eocd[i+3] == 0x06) { + for (size_t i = 4; i < eocd_size - 3; ++i) { + if (eocd[i] == 0x50 && eocd[i + 1] == 0x4b && eocd[i + 2] == 0x05 && eocd[i + 3] == 0x06) { // If the sequence $50 $4b $05 $06 appears anywhere after the real one, libziparchive will // find the later (wrong) one, which could be exploitable. Fail the verification if this // sequence occurs anywhere after the real one. @@ -203,8 +198,12 @@ int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys bool need_sha256 = false; for (const auto& key : keys) { switch (key.hash_len) { - case SHA_DIGEST_LENGTH: need_sha1 = true; break; - case SHA256_DIGEST_LENGTH: need_sha256 = true; break; + case SHA_DIGEST_LENGTH: + need_sha1 = true; + break; + case SHA256_DIGEST_LENGTH: + need_sha256 = true; + break; } } @@ -247,8 +246,8 @@ int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys const uint8_t* signature = eocd + eocd_size - signature_start; size_t signature_size = signature_start - FOOTER_SIZE; - LOG(INFO) << "signature (offset: " << std::hex << (length - signature_start) << ", length: " - << signature_size << "): " << print_hex(signature, signature_size); + LOG(INFO) << "signature (offset: " << std::hex << (length - signature_start) + << ", length: " << signature_size << "): " << print_hex(signature, signature_size); std::vector<uint8_t> sig_der; if (!read_pkcs7(signature, signature_size, &sig_der)) { @@ -373,8 +372,8 @@ bool CheckRSAKey(const std::unique_ptr<RSA, RSADeleter>& rsa) { const BIGNUM* out_e; RSA_get0_key(rsa.get(), &out_n, &out_e, nullptr /* private exponent */); auto modulus_bits = BN_num_bits(out_n); - if (modulus_bits != 2048) { - LOG(ERROR) << "Modulus should be 2048 bits long, actual: " << modulus_bits; + if (modulus_bits != 2048 && modulus_bits != 4096) { + LOG(ERROR) << "Modulus should be 2048 or 4096 bits long, actual: " << modulus_bits; return false; } |