diff options
Diffstat (limited to 'fs_mgr/fs_mgr_overlayfs.cpp')
| -rw-r--r-- | fs_mgr/fs_mgr_overlayfs.cpp | 111 |
1 files changed, 64 insertions, 47 deletions
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 87729cda1..9364b2df6 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -78,6 +78,10 @@ bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) { #if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs +Fstab fs_mgr_overlayfs_candidate_list(const Fstab&) { + return {}; +} + bool fs_mgr_overlayfs_mount_all(Fstab*) { return false; } @@ -238,8 +242,7 @@ std::string fs_mgr_get_overlayfs_options(const std::string& mount_point) { return ret; } -const char* fs_mgr_mount_point(const char* mount_point) { - if (!mount_point) return mount_point; +const std::string fs_mgr_mount_point(const std::string& mount_point) { if ("/"s != mount_point) return mount_point; return "/system"; } @@ -526,40 +529,6 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) { } } -std::vector<std::string> fs_mgr_candidate_list(Fstab* fstab, const char* mount_point = nullptr) { - std::vector<std::string> mounts; - for (auto& entry : *fstab) { - if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) && - !fs_mgr_wants_overlayfs(&entry)) { - continue; - } - std::string new_mount_point(fs_mgr_mount_point(entry.mount_point.c_str())); - if (mount_point && (new_mount_point != mount_point)) continue; - - auto saved_errno = errno; - auto verity_enabled = fs_mgr_is_verity_enabled(entry); - if (errno == ENOENT || errno == ENXIO) errno = saved_errno; - if (verity_enabled) continue; - - auto duplicate_or_more_specific = false; - for (auto it = mounts.begin(); it != mounts.end();) { - if ((*it == new_mount_point) || - (android::base::StartsWith(new_mount_point, *it + "/"))) { - duplicate_or_more_specific = true; - break; - } - if (android::base::StartsWith(*it, new_mount_point + "/")) { - it = mounts.erase(it); - } else { - ++it; - } - } - if (!duplicate_or_more_specific) mounts.emplace_back(new_mount_point); - } - - return mounts; -} - // Mount kScratchMountPoint bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::string mnt_type, bool readonly = false) { @@ -802,12 +771,42 @@ bool fs_mgr_overlayfs_invalid() { } // namespace +Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) { + Fstab candidates; + for (const auto& entry : fstab) { + FstabEntry new_entry = entry; + if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) && + !fs_mgr_wants_overlayfs(&new_entry)) { + continue; + } + auto new_mount_point = fs_mgr_mount_point(entry.mount_point); + auto duplicate_or_more_specific = false; + for (auto it = candidates.begin(); it != candidates.end();) { + auto it_mount_point = fs_mgr_mount_point(it->mount_point); + if ((it_mount_point == new_mount_point) || + (android::base::StartsWith(new_mount_point, it_mount_point + "/"))) { + duplicate_or_more_specific = true; + break; + } + if (android::base::StartsWith(it_mount_point, new_mount_point + "/")) { + it = candidates.erase(it); + } else { + ++it; + } + } + if (!duplicate_or_more_specific) candidates.emplace_back(std::move(new_entry)); + } + return candidates; +} + bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { auto ret = false; if (fs_mgr_overlayfs_invalid()) return ret; auto scratch_can_be_mounted = true; - for (const auto& mount_point : fs_mgr_candidate_list(fstab)) { + for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) { + if (fs_mgr_is_verity_enabled(entry)) continue; + auto mount_point = fs_mgr_mount_point(entry.mount_point); if (fs_mgr_overlayfs_already_mounted(mount_point)) { ret = true; continue; @@ -840,8 +839,9 @@ std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab) { return {}; } - for (const auto& mount_point : fs_mgr_candidate_list(fstab)) { - if (fs_mgr_overlayfs_already_mounted(mount_point)) continue; + for (const auto& entry : fs_mgr_overlayfs_candidate_list(*fstab)) { + if (fs_mgr_is_verity_enabled(entry)) continue; + if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) continue; auto device = fs_mgr_overlayfs_scratch_device(); if (!fs_mgr_overlayfs_scratch_can_be_mounted(device)) break; return {device}; @@ -867,8 +867,24 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return false; } errno = save_errno; - auto mounts = fs_mgr_candidate_list(&fstab, fs_mgr_mount_point(mount_point)); - if (mounts.empty()) return ret; + auto candidates = fs_mgr_overlayfs_candidate_list(fstab); + for (auto it = candidates.begin(); it != candidates.end();) { + if (mount_point && + (fs_mgr_mount_point(it->mount_point) != fs_mgr_mount_point(mount_point))) { + it = candidates.erase(it); + continue; + } + save_errno = errno; + auto verity_enabled = fs_mgr_is_verity_enabled(*it); + if (errno == ENOENT || errno == ENXIO) errno = save_errno; + if (verity_enabled) { + it = candidates.erase(it); + continue; + } + ++it; + } + + if (candidates.empty()) return ret; std::string dir; for (const auto& overlay_mount_point : kOverlayMountPoints) { @@ -891,8 +907,8 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* std::string overlay; ret |= fs_mgr_overlayfs_setup_dir(dir, &overlay, change); - for (const auto& fsrec_mount_point : mounts) { - ret |= fs_mgr_overlayfs_setup_one(overlay, fsrec_mount_point, change); + for (const auto& entry : candidates) { + ret |= fs_mgr_overlayfs_setup_one(overlay, fs_mgr_mount_point(entry.mount_point), change); } return ret; } @@ -901,7 +917,6 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* // If something is altered, set *change. bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { if (change) *change = false; - mount_point = fs_mgr_mount_point(mount_point); auto ret = true; // If scratch exists, but is not mounted, lets gain access to clean // specific override entries. @@ -919,7 +934,8 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { fs_mgr_overlayfs_scratch_mount_type()); } for (const auto& overlay_mount_point : kOverlayMountPoints) { - ret &= fs_mgr_overlayfs_teardown_one(overlay_mount_point, mount_point ?: "", change); + ret &= fs_mgr_overlayfs_teardown_one( + overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change); } if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { // After obligatory teardown to make sure everything is clean, but if @@ -946,8 +962,9 @@ bool fs_mgr_overlayfs_is_setup() { return false; } if (fs_mgr_overlayfs_invalid()) return false; - for (const auto& mount_point : fs_mgr_candidate_list(&fstab)) { - if (fs_mgr_overlayfs_already_mounted(mount_point)) return true; + for (const auto& entry : fs_mgr_overlayfs_candidate_list(fstab)) { + if (fs_mgr_is_verity_enabled(entry)) continue; + if (fs_mgr_overlayfs_already_mounted(fs_mgr_mount_point(entry.mount_point))) return true; } return false; } |
