diff options
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | install/include/install/install.h | 4 | ||||
-rw-r--r-- | install/install.cpp | 47 | ||||
-rw-r--r-- | recovery.cpp | 12 | ||||
-rw-r--r-- | tests/Android.bp | 1 | ||||
-rw-r--r-- | tests/unit/install_test.cpp | 28 | ||||
-rw-r--r-- | tools/recovery_l10n/res/values-gl/strings.xml | 4 | ||||
-rw-r--r-- | tools/recovery_l10n/res/values-in/strings.xml | 2 | ||||
-rw-r--r-- | tools/recovery_l10n/res/values-ja/strings.xml | 2 |
9 files changed, 90 insertions, 11 deletions
diff --git a/Android.bp b/Android.bp index d78c3fa94..1ae8ff78d 100644 --- a/Android.bp +++ b/Android.bp @@ -68,6 +68,7 @@ cc_defaults { ], static_libs: [ + "libc++fs", "libinstall", "librecovery_fastboot", "libminui", diff --git a/install/include/install/install.h b/install/include/install/install.h index b4b3a9149..c3331c8bf 100644 --- a/install/include/install/install.h +++ b/install/include/install/install.h @@ -67,3 +67,7 @@ bool verify_package_compatibility(ZipArchiveHandle package_zip); // pre-device and serial number (if presents). A/B OTA specific checks: pre-build version, // fingerprint, timestamp. bool CheckPackageMetadata(const std::map<std::string, std::string>& metadata, OtaType ota_type); + +// 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); diff --git a/install/install.cpp b/install/install.cpp index 9166f9cfb..43916b3d8 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> @@ -722,3 +723,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 f59a940fc..633734285 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -674,13 +674,11 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri set_retry_bootloader_message(retry_count + 1, args); } - if (update_package[0] == '@') { - ensure_path_mounted(update_package + 1); - } else { - ensure_path_mounted(update_package); - } - - if (install_with_fuse) { + 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 (install_with_fuse || should_use_fuse) { LOG(INFO) << "Installing package " << update_package << " with fuse"; status = InstallWithFuseFromPath(update_package, ui); } else if (auto memory_package = Package::CreateMemoryPackage( diff --git a/tests/Android.bp b/tests/Android.bp index 5b881e367..ec49c07af 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -94,6 +94,7 @@ librecovery_static_libs = [ "liblp", "libvndksupport", "libtinyxml2", + "libc++fs", ] cc_test { diff --git a/tests/unit/install_test.cpp b/tests/unit/install_test.cpp index 4ec409908..60cdc1105 100644 --- a/tests/unit/install_test.cpp +++ b/tests/unit/install_test.cpp @@ -36,6 +36,7 @@ #include "install/wipe_device.h" #include "otautil/paths.h" #include "private/setup_commands.h" +#include "recovery_utils/roots.h" static void BuildZipArchive(const std::map<std::string, std::string>& file_map, int fd, int compression_type) { @@ -595,3 +596,30 @@ TEST(InstallTest, CheckPackageMetadata_ab_post_timestamp) { "\n"); TestCheckPackageMetadata(metadata, OtaType::AB, true); } + +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-gl/strings.xml b/tools/recovery_l10n/res/values-gl/strings.xml index e51b36dfb..e6f2ffd84 100644 --- a/tools/recovery_l10n/res/values-gl/strings.xml +++ b/tools/recovery_l10n/res/values-gl/strings.xml @@ -6,9 +6,9 @@ <string name="recovery_no_command" msgid="4465476568623024327">"Non hai ningún comando"</string> <string name="recovery_error" msgid="5748178989622716736">"Erro"</string> <string name="recovery_installing_security" msgid="9184031299717114342">"Instalando actualización de seguranza"</string> - <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Non se puido cargar o sistema Android. Os teus datos poden estar danados. Se segue aparecendo esta mensaxe, pode ser necesario restablecer os datos de fábrica e borrar todos os datos de usuario almacenados neste dispositivo."</string> + <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Non se puido cargar o sistema Android. Os teus datos poden estar danados. Se segue aparecendo esta mensaxe, pode ser necesario restablecer os datos de fábrica e borrar todos os datos do usuario almacenados neste dispositivo."</string> <string name="recovery_try_again" msgid="7168248750158873496">"Tentar de novo"</string> <string name="recovery_factory_data_reset" msgid="7321351565602894783">"Restablecemento dos datos de fábrica"</string> - <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Queres borrar todos os datos de usuario?\n\n ESTA ACCIÓN NON SE PODE DESFACER."</string> + <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Queres borrar todos os datos do usuario?\n\n ESTA ACCIÓN NON SE PODE DESFACER."</string> <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"Cancelar"</string> </resources> diff --git a/tools/recovery_l10n/res/values-in/strings.xml b/tools/recovery_l10n/res/values-in/strings.xml index 15a78ec48..43c9deb94 100644 --- a/tools/recovery_l10n/res/values-in/strings.xml +++ b/tools/recovery_l10n/res/values-in/strings.xml @@ -9,6 +9,6 @@ <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Tidak dapat memuat sistem Android. Data Anda mungkin rusak. Jika terus mendapatkan pesan ini, Anda mungkin perlu melakukan reset ke setelan pabrik dan menghapus semua data pengguna yang disimpan di perangkat ini."</string> <string name="recovery_try_again" msgid="7168248750158873496">"Coba lagi"</string> <string name="recovery_factory_data_reset" msgid="7321351565602894783">"Reset ke setelan pabrik"</string> - <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Wipe semua data pengguna?\n\n TINDAKAN INI TIDAK DAPAT DIURUNGKAN!"</string> + <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Hapus total semua data pengguna?\n\n TINDAKAN INI TIDAK DAPAT DIURUNGKAN!"</string> <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"Batal"</string> </resources> diff --git a/tools/recovery_l10n/res/values-ja/strings.xml b/tools/recovery_l10n/res/values-ja/strings.xml index 3d6637278..2d6c0abc4 100644 --- a/tools/recovery_l10n/res/values-ja/strings.xml +++ b/tools/recovery_l10n/res/values-ja/strings.xml @@ -6,7 +6,7 @@ <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_wipe_data_confirmation" msgid="5439823343348043954">"すべてのユーザー データをワイプしますか?\n\nこの操作は元に戻せません。"</string> |