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 a8e032e21..8b7c4b82d 100644 --- a/Android.bp +++ b/Android.bp @@ -72,6 +72,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 87d43ab09..bef23e9ca 100644 --- a/install/include/install/install.h +++ b/install/include/install/install.h @@ -63,3 +63,7 @@ bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::st // 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 4bb0903cc..1c9bf2fd2 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> @@ -641,3 +642,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 e4b8e45fb..582ca48a5 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -681,13 +681,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 e49d966c7..640bb042e 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -93,6 +93,7 @@ librecovery_static_libs = [ "libbinderthreadstate", "liblp", "libtinyxml2", + "libc++fs", ] cc_test { diff --git a/tests/unit/install_test.cpp b/tests/unit/install_test.cpp index 370fbdcc5..ee753494c 100644 --- a/tests/unit/install_test.cpp +++ b/tests/unit/install_test.cpp @@ -35,6 +35,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) { @@ -513,3 +514,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> |