From 9032b39ea50033b6779952423c573e1ca953f073 Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Wed, 18 Oct 2023 19:22:57 +0800 Subject: [PATCH] fs_mgr_overlayfs: Setup remount scratch dir with encoded mountpoint name Instead of using the basename(mounpoint) as partition scratch dir name, which could lead to name collision, use the normalized and encoded mountpoint as scratch dir name. Bug: 243503963 Bug: 306124139 Test: adb-remount-test Change-Id: I5a64f17bc3b88f0ce42bd0c5779c8dd23a07917f --- fs_mgr/fs_mgr_overlayfs_control.cpp | 9 ++--- fs_mgr/fs_mgr_overlayfs_mount.cpp | 56 ++++++++++++++++------------- fs_mgr/fs_mgr_overlayfs_mount.h | 1 + 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs_control.cpp b/fs_mgr/fs_mgr_overlayfs_control.cpp index 2cc0d2d5e..50d8280e9 100644 --- a/fs_mgr/fs_mgr_overlayfs_control.cpp +++ b/fs_mgr/fs_mgr_overlayfs_control.cpp @@ -144,7 +144,8 @@ bool fs_mgr_overlayfs_setup_one(const std::string& overlay, const std::string& m if (fs_mgr_overlayfs_already_mounted(mount_point)) { return true; } - auto fsrec_mount_point = overlay + "/" + android::base::Basename(mount_point) + "/"; + const auto base = GetEncodedBaseDirForMountPoint(mount_point); + auto fsrec_mount_point = overlay + "/" + base + "/"; AutoSetFsCreateCon createcon(kOverlayfsFileContext); if (!createcon.Ok()) { @@ -286,10 +287,10 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string } auto cleanup_all = mount_point.empty(); - const auto partition_name = android::base::Basename(mount_point); - const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name)); + const auto base = GetEncodedBaseDirForMountPoint(mount_point); + const auto oldpath = top + (cleanup_all ? "" : ("/" + base)); const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir + ".teardown" - : top + "/." + partition_name + ".teardown"; + : top + "/." + base + ".teardown"; auto ret = fs_mgr_rm_all(newpath); if (!rename(oldpath.c_str(), newpath.c_str())) { if (change) *change = true; diff --git a/fs_mgr/fs_mgr_overlayfs_mount.cpp b/fs_mgr/fs_mgr_overlayfs_mount.cpp index 9f17c06f7..0dadbffc6 100644 --- a/fs_mgr/fs_mgr_overlayfs_mount.cpp +++ b/fs_mgr/fs_mgr_overlayfs_mount.cpp @@ -60,6 +60,7 @@ constexpr char kPhysicalDevice[] = "/dev/block/by-name/"; constexpr char kLowerdirOption[] = "lowerdir="; constexpr char kUpperdirOption[] = "upperdir="; +constexpr char kWorkdirOption[] = "workdir="; bool fs_mgr_is_dsu_running() { // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is @@ -89,6 +90,14 @@ std::vector OverlayMountPoints() { return {kScratchMountPoint, kCacheMountPoint}; } +std::string GetEncodedBaseDirForMountPoint(const std::string& mount_point) { + std::string normalized_path; + if (mount_point.empty() || !android::base::Realpath(mount_point, &normalized_path)) { + return ""; + } + return android::base::StringReplace(normalized_path, "/", "@", true); +} + static bool fs_mgr_is_dir(const std::string& path) { struct stat st; return !stat(path.c_str(), &st) && S_ISDIR(st.st_mode); @@ -202,21 +211,6 @@ static bool fs_mgr_overlayfs_enabled(FstabEntry* entry) { return has_shared_blocks; } -static std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) { - if (!fs_mgr_is_dir(mount_point)) return ""; - const auto base = android::base::Basename(mount_point) + "/"; - for (const auto& overlay_mount_point : OverlayMountPoints()) { - auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base; - auto upper = dir + kUpperName; - if (!fs_mgr_is_dir(upper)) continue; - auto work = dir + kWorkName; - if (!fs_mgr_is_dir(work)) continue; - if (access(work.c_str(), R_OK | W_OK)) continue; - return dir; - } - return ""; -} - const std::string fs_mgr_mount_point(const std::string& mount_point) { if ("/"s != mount_point) return mount_point; return "/system"; @@ -225,16 +219,30 @@ const std::string fs_mgr_mount_point(const std::string& mount_point) { // default options for mount_point, returns empty string for none available. static std::string fs_mgr_get_overlayfs_options(const FstabEntry& entry) { const auto mount_point = fs_mgr_mount_point(entry.mount_point); - auto candidate = fs_mgr_get_overlayfs_candidate(mount_point); - if (candidate.empty()) return ""; - auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName + - ",workdir=" + candidate + kWorkName + android::fs_mgr::CheckOverlayfs().mount_flags; - for (const auto& flag : android::base::Split(entry.fs_options, ",")) { - if (android::base::StartsWith(flag, "context=")) { - ret += "," + flag; - } + if (!fs_mgr_is_dir(mount_point)) { + return ""; } - return ret; + const auto base = GetEncodedBaseDirForMountPoint(mount_point); + if (base.empty()) { + return ""; + } + for (const auto& overlay_mount_point : OverlayMountPoints()) { + const auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base + "/"; + const auto upper = dir + kUpperName; + const auto work = dir + kWorkName; + if (!fs_mgr_is_dir(upper) || !fs_mgr_is_dir(work) || access(work.c_str(), R_OK | W_OK)) { + continue; + } + auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + upper + "," + + kWorkdirOption + work + android::fs_mgr::CheckOverlayfs().mount_flags; + for (const auto& flag : android::base::Split(entry.fs_options, ",")) { + if (android::base::StartsWith(flag, "context=")) { + ret += "," + flag; + } + } + return ret; + } + return ""; } bool AutoSetFsCreateCon::Set(const std::string& context) { diff --git a/fs_mgr/fs_mgr_overlayfs_mount.h b/fs_mgr/fs_mgr_overlayfs_mount.h index f0afac1ed..98b9007b5 100644 --- a/fs_mgr/fs_mgr_overlayfs_mount.h +++ b/fs_mgr/fs_mgr_overlayfs_mount.h @@ -58,3 +58,4 @@ std::vector OverlayMountPoints(); bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true); bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry); android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab); +std::string GetEncodedBaseDirForMountPoint(const std::string& mount_point);