diff options
| author | Kevin F. Haggerty <haggertk@lineageos.org> | 2020-06-01 21:07:15 -0600 |
|---|---|---|
| committer | Kevin F. Haggerty <haggertk@lineageos.org> | 2020-06-01 21:38:40 -0600 |
| commit | 165d84ba502e3ad181ac4c1b355f1dfc3c130637 (patch) | |
| tree | ef2b8dcca182837aba80ce886e0345fb3552b48b | |
| parent | b7913a0de39ba0b53989c5b4f4260221b7109796 (diff) | |
| parent | 6943af1f7d00de4fabccbcfe03077983a5ae771a (diff) | |
| download | android_bootable_recovery-165d84ba502e3ad181ac4c1b355f1dfc3c130637.tar.gz android_bootable_recovery-165d84ba502e3ad181ac4c1b355f1dfc3c130637.tar.bz2 android_bootable_recovery-165d84ba502e3ad181ac4c1b355f1dfc3c130637.zip | |
Merge tag 'android-10.0.0_r37' into staging/lineage-17.1_merge-android-10.0.0_r37
Android 10.0.0 Release 37 (QQ3A.200605.001)
* tag 'android-10.0.0_r37':
Import translations. DO NOT MERGE
Force package installation with FUSE unless the package stores on device
Conflicts:
install/include/install/install.h
recovery.cpp
Change-Id: I8db96fa3db40754daff714872970965d169557ab
| -rw-r--r-- | Android.bp | 2 | ||||
| -rw-r--r-- | install/include/install/install.h | 6 | ||||
| -rw-r--r-- | install/install.cpp | 47 | ||||
| -rw-r--r-- | recovery.cpp | 27 | ||||
| -rw-r--r-- | tests/Android.bp | 1 | ||||
| -rw-r--r-- | tests/component/install_test.cpp | 28 | ||||
| -rw-r--r-- | tools/recovery_l10n/res/values-ar/strings.xml | 4 | ||||
| -rw-r--r-- | tools/recovery_l10n/res/values-hy/strings.xml | 2 |
8 files changed, 111 insertions, 6 deletions
@@ -71,6 +71,7 @@ cc_defaults { ], static_libs: [ + "libc++fs", "libinstall", "librecovery_fastboot", "libminui", @@ -96,6 +97,7 @@ cc_library_static { ], shared_libs: [ + "libfusesideload", "librecovery_ui", ], } diff --git a/install/include/install/install.h b/install/include/install/install.h index 85c197de..84ff7134 100644 --- a/install/include/install/install.h +++ b/install/include/install/install.h @@ -74,6 +74,10 @@ bool verify_package_compatibility(ZipArchiveHandle package_zip); int CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type, bool allow_ab_downgrade = false); +// 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. +bool SetupPackageMount(const std::string& package_path, bool* should_use_fuse); + // Defined in recovery.cpp, just declare it and it will eventually link fine. bool ask_to_continue_unverified(Device* device); -bool ask_to_continue_downgrade(Device* device);
\ No newline at end of file +bool ask_to_continue_downgrade(Device* device); diff --git a/install/install.cpp b/install/install.cpp index a417d18e..762c4572 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -30,6 +30,7 @@ #include <atomic> #include <chrono> #include <condition_variable> +#include <filesystem> #include <functional> #include <limits> #include <mutex> @@ -732,3 +733,49 @@ bool verify_package(Package* package, RecoveryUI* ui) { } return true; } + +bool SetupPackageMount(const std::string& package_path, bool* should_use_fuse) { + CHECK(should_use_fuse != nullptr); + + if (package_path.empty()) { + return false; + } + + *should_use_fuse = true; + if (package_path[0] == '@') { + auto block_map_path = package_path.substr(1); + if (ensure_path_mounted(block_map_path) != 0) { + LOG(ERROR) << "Failed to mount " << block_map_path; + return false; + } + // uncrypt only produces block map only if the package stays on /data. + *should_use_fuse = false; + return true; + } + + // Package is not a block map file. + if (ensure_path_mounted(package_path) != 0) { + LOG(ERROR) << "Failed to mount " << package_path; + return false; + } + + // Reject the package if the input path doesn't equal the canonicalized path. + // e.g. /cache/../sdcard/update_package. + std::error_code ec; + auto canonical_path = std::filesystem::canonical(package_path, ec); + if (ec) { + LOG(ERROR) << "Failed to get canonical of " << package_path << ", " << ec.message(); + return false; + } + if (canonical_path.string() != package_path) { + LOG(ERROR) << "Installation aborts. The canonical path " << canonical_path.string() + << " doesn't equal the original path " << package_path; + return false; + } + + constexpr const char* CACHE_ROOT = "/cache"; + if (android::base::StartsWith(package_path, CACHE_ROOT)) { + *should_use_fuse = false; + } + return true; +} diff --git a/recovery.cpp b/recovery.cpp index 6e8b17c9..60553b7f 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -51,6 +51,7 @@ #include "common.h" #include "fsck_unshare_blocks.h" +#include "fuse_sideload.h" #include "install/adb_install.h" #include "install/fuse_sdcard_install.h" #include "install/install.h" @@ -984,8 +985,30 @@ 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, - true /* verify */, false /* allow_ab_downgrade */, ui); + bool should_use_fuse = false; + if (!SetupPackageMount(update_package, &should_use_fuse)) { + LOG(INFO) << "Failed to set up the package access, skipping installation"; + status = INSTALL_ERROR; + } else if (should_use_fuse) { + LOG(INFO) << "Installing package " << update_package << " with fuse"; + auto file_data_reader = std::make_unique<FuseFileDataProvider>(update_package, 65536); + status = run_fuse_sideload(std::move(file_data_reader)); + } else if (auto memory_package = Package::CreateMemoryPackage( + update_package, + std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1)); + memory_package != nullptr) { + status = install_package(update_package, should_wipe_cache, true, retry_count, + true /* verify */, false /* allow_ab_downgrade */, ui); + } else { + // We may fail to memory map the package on 32 bit builds for packages with 2GiB+ size. + // In such cases, we will try to install the package with fuse. This is not the default + // installation method because it introduces a layer of indirection from the kernel space. + LOG(WARNING) << "Failed to memory map package " << update_package + << "; falling back to install with fuse"; + auto file_data_reader = std::make_unique<FuseFileDataProvider>(update_package, 65536); + status = run_fuse_sideload(std::move(file_data_reader)); + } + if (status != INSTALL_SUCCESS) { ui->Print("Installation aborted.\n"); diff --git a/tests/Android.bp b/tests/Android.bp index 09ef716d..a0d82d5f 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -99,6 +99,7 @@ librecovery_static_libs = [ "liblp", "libvndksupport", "libtinyxml2", + "libc++fs", ] cc_test { diff --git a/tests/component/install_test.cpp b/tests/component/install_test.cpp index 38513293..c1f0ca81 100644 --- a/tests/component/install_test.cpp +++ b/tests/component/install_test.cpp @@ -34,6 +34,7 @@ #include "install/install.h" #include "otautil/paths.h" +#include "otautil/roots.h" #include "private/setup_commands.h" static void BuildZipArchive(const std::map<std::string, std::string>& file_map, int fd, @@ -595,3 +596,30 @@ TEST(InstallTest, CheckPackageMetadata_ab_post_timestamp) { "\n"); test_check_package_metadata(metadata, OtaType::AB, 0); } + +TEST(InstallTest, SetupPackageMount_package_path) { + load_volume_table(); + bool install_with_fuse; + + // Setup should fail if the input path doesn't exist. + ASSERT_FALSE(SetupPackageMount("/does_not_exist", &install_with_fuse)); + + // Package should be installed with fuse if it's not in /cache. + TemporaryDir temp_dir; + TemporaryFile update_package(temp_dir.path); + ASSERT_TRUE(SetupPackageMount(update_package.path, &install_with_fuse)); + ASSERT_TRUE(install_with_fuse); + + // Setup should fail if the input path isn't canonicalized. + std::string uncanonical_package_path = android::base::Join( + std::vector<std::string>{ + temp_dir.path, + "..", + android::base::Basename(temp_dir.path), + android::base::Basename(update_package.path), + }, + '/'); + + ASSERT_EQ(0, access(uncanonical_package_path.c_str(), R_OK)); + ASSERT_FALSE(SetupPackageMount(uncanonical_package_path, &install_with_fuse)); +} diff --git a/tools/recovery_l10n/res/values-ar/strings.xml b/tools/recovery_l10n/res/values-ar/strings.xml index 2af36d64..a9cd2d13 100644 --- a/tools/recovery_l10n/res/values-ar/strings.xml +++ b/tools/recovery_l10n/res/values-ar/strings.xml @@ -6,9 +6,9 @@ <string name="recovery_no_command" msgid="4465476568623024327">"ليس هناك أي أمر"</string> <string name="recovery_error" msgid="5748178989622716736">"خطأ!"</string> <string name="recovery_installing_security" msgid="9184031299717114342">"جارٍ تثبيت تحديث الأمان"</string> - <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط بحسب بيانات المصنع ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز."</string> + <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط على الإعدادات الأصلية ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز."</string> <string name="recovery_try_again" msgid="7168248750158873496">"إعادة المحاولة"</string> - <string name="recovery_factory_data_reset" msgid="7321351565602894783">"إعادة الضبط بحسب بيانات المصنع"</string> + <string name="recovery_factory_data_reset" msgid="7321351565602894783">"إعادة الضبط على الإعدادات الأصلية"</string> <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"هل تريد حجب كل بيانات المستخدم؟\n\n لا يمكن التراجع عن هذا الإجراء."</string> <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"إلغاء"</string> </resources> diff --git a/tools/recovery_l10n/res/values-hy/strings.xml b/tools/recovery_l10n/res/values-hy/strings.xml index 35a0ab11..76c28a70 100644 --- a/tools/recovery_l10n/res/values-hy/strings.xml +++ b/tools/recovery_l10n/res/values-hy/strings.xml @@ -9,6 +9,6 @@ <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Չհաջողվեց բեռնել Android համակարգը։ Հնարավոր է՝ ձեր տվյալները վնասված են։ Եթե նորից տեսնեք այս հաղորդագրությունը, փորձեք վերակայել սարքի կարգավորումները և ջնջել օգտատիրոջ բոլոր տվյալները։"</string> <string name="recovery_try_again" msgid="7168248750158873496">"Նորից փորձել"</string> <string name="recovery_factory_data_reset" msgid="7321351565602894783">"Վերակայել բոլոր տվյալները"</string> - <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Մաքրե՞լ օգտատիրոջ բոլոր տվյալները։\n\n ԱՅՍ ԳՈՐԾՈՂՈՒԹՅՈՒՆԸ ՀՆԱՐԱՎՈՐ ՉԻ ԼԻՆԻ ՀԵՏԱՐԿԵԼ"</string> + <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Ջնջե՞լ օգտատիրոջ բոլոր տվյալները։\n\n ԱՅՍ ԳՈՐԾՈՂՈՒԹՅՈՒՆԸ ՀՆԱՐԱՎՈՐ ՉԻ ԼԻՆԻ ՀԵՏԱՐԿԵԼ"</string> <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"Չեղարկել"</string> </resources> |
