Loading fs_mgr/fs_mgr_overlayfs.cpp +25 −20 Original line number Diff line number Diff line Loading @@ -85,6 +85,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 bool fs_mgr_wants_overlayfs(FstabEntry*) { return false; } Fstab fs_mgr_overlayfs_candidate_list(const Fstab&) { return {}; } Loading Loading @@ -388,26 +392,6 @@ bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overl return false; } bool fs_mgr_wants_overlayfs(FstabEntry* entry) { // Don't check entries that are managed by vold. if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false; // *_other doesn't want overlayfs. if (entry->fs_mgr_flags.slot_select_other) return false; // Only concerned with readonly partitions. if (!(entry->flags & MS_RDONLY)) return false; // If unbindable, do not allow overlayfs as this could expose us to // security issues. On Android, this could also be used to turn off // the ability to overlay an otherwise acceptable filesystem since // /system and /vendor are never bound(sic) to. if (entry->flags & MS_UNBINDABLE) return false; if (!fs_mgr_overlayfs_enabled(entry)) return false; return true; } constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0"; bool fs_mgr_overlayfs_setup_dir(const std::string& dir, std::string* overlay, bool* change) { Loading Loading @@ -1284,6 +1268,27 @@ bool fs_mgr_overlayfs_invalid() { } // namespace bool fs_mgr_wants_overlayfs(FstabEntry* entry) { // Don't check entries that are managed by vold. if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false; // *_other doesn't want overlayfs. if (entry->fs_mgr_flags.slot_select_other) return false; // Only concerned with readonly partitions. if (!(entry->flags & MS_RDONLY)) return false; // If unbindable, do not allow overlayfs as this could expose us to // security issues. On Android, this could also be used to turn off // the ability to overlay an otherwise acceptable filesystem since // /system and /vendor are never bound(sic) to. if (entry->flags & MS_UNBINDABLE) return false; if (!fs_mgr_overlayfs_enabled(entry)) return false; return true; } Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) { Fstab candidates; for (const auto& entry : fstab) { Loading fs_mgr/fs_mgr_remount.cpp +77 −57 Original line number Diff line number Diff line Loading @@ -261,6 +261,74 @@ static RemountStatus GetRemountList(const Fstab& fstab, const std::vector<std::s return REMOUNT_SUCCESS; } struct RemountCheckResult { bool reboot_later = false; bool setup_overlayfs = false; bool disabled_verity = false; bool verity_error = false; }; static RemountStatus CheckVerity(const FstabEntry& entry, RemountCheckResult* result) { if (!fs_mgr_is_verity_enabled(entry)) { return REMOUNT_SUCCESS; } if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked") { return VERITY_PARTITION; } bool ok = false; std::unique_ptr<AvbOps, decltype(&::avb_ops_user_free)> ops(avb_ops_user_new(), &::avb_ops_user_free); if (ops) { auto suffix = android::base::GetProperty("ro.boot.slot_suffix", ""); ok = avb_user_verity_set(ops.get(), suffix.c_str(), false); } if (!ok && fs_mgr_set_blk_ro(entry.blk_device, false)) { fec::io fh(entry.blk_device.c_str(), O_RDWR); ok = fh && fh.set_verity_status(false); } if (!ok) { return VERITY_PARTITION; } result->disabled_verity = true; result->reboot_later = true; return REMOUNT_SUCCESS; } static RemountStatus CheckVerityAndOverlayfs(Fstab* partitions, RemountCheckResult* result) { RemountStatus status = REMOUNT_SUCCESS; for (auto it = partitions->begin(); it != partitions->end();) { auto& entry = *it; const auto& mount_point = entry.mount_point; if (auto rv = CheckVerity(entry, result); rv != REMOUNT_SUCCESS) { LOG(ERROR) << "Skipping verified partition " << mount_point << " for remount"; status = rv; it = partitions->erase(it); continue; } if (fs_mgr_wants_overlayfs(&entry)) { bool change = false; bool force = result->disabled_verity; if (!fs_mgr_overlayfs_setup(nullptr, mount_point.c_str(), &change, force)) { LOG(ERROR) << "Overlayfs setup for " << mount_point << " failed, skipping"; status = BAD_OVERLAY; it = partitions->erase(it); continue; } if (change) { LOG(INFO) << "Using overlayfs for " << mount_point; result->reboot_later = true; result->setup_overlayfs = true; } } it++; } return status; } static int do_remount(int argc, char* argv[]) { RemountStatus retval = REMOUNT_SUCCESS; Loading Loading @@ -342,64 +410,16 @@ static int do_remount(int argc, char* argv[]) { } // Check verity and optionally setup overlayfs backing. auto reboot_later = false; auto user_please_reboot_later = false; auto setup_overlayfs = false; auto just_disabled_verity = false; for (auto it = partitions.begin(); it != partitions.end();) { auto& entry = *it; auto& mount_point = entry.mount_point; if (fs_mgr_is_verity_enabled(entry)) { retval = VERITY_PARTITION; auto ret = false; if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") != "locked") { if (AvbOps* ops = avb_ops_user_new()) { ret = avb_user_verity_set( ops, android::base::GetProperty("ro.boot.slot_suffix", "").c_str(), false); avb_ops_user_free(ops); } if (!ret && fs_mgr_set_blk_ro(entry.blk_device, false)) { fec::io fh(entry.blk_device.c_str(), O_RDWR); ret = fh && fh.set_verity_status(false); } if (ret) { LOG(WARNING) << "Disabling verity for " << mount_point; just_disabled_verity = true; reboot_later = can_reboot; user_please_reboot_later = true; } } if (!ret) { LOG(ERROR) << "Skipping " << mount_point << " for remount"; it = partitions.erase(it); continue; } } RemountCheckResult check_result; retval = CheckVerityAndOverlayfs(&partitions, &check_result); auto change = false; errno = 0; if (fs_mgr_overlayfs_setup(nullptr, mount_point.c_str(), &change, just_disabled_verity)) { if (change) { LOG(INFO) << "Using overlayfs for " << mount_point; reboot_later = can_reboot; user_please_reboot_later = true; setup_overlayfs = true; } } else if (errno) { PLOG(ERROR) << "Overlayfs setup for " << mount_point << " failed, skipping"; retval = BAD_OVERLAY; it = partitions.erase(it); continue; } ++it; } bool auto_reboot = check_result.reboot_later && can_reboot; // If (1) remount requires a reboot to take effect, (2) system is currently // running a DSU guest and (3) DSU is disabled, then enable DSU so that the // next reboot would not take us back to the host system but stay within // the guest system. if (reboot_later) { if (auto_reboot) { if (auto gsid = android::gsi::GetGsiService()) { auto dsu_running = false; if (auto status = gsid->isGsiRunning(&dsu_running); !status.isOk()) { Loading Loading @@ -430,9 +450,9 @@ static int do_remount(int argc, char* argv[]) { } } if (partitions.empty() || just_disabled_verity) { if (reboot_later) reboot(setup_overlayfs); if (user_please_reboot_later) { if (partitions.empty() || check_result.disabled_verity) { if (auto_reboot) reboot(check_result.setup_overlayfs); if (check_result.reboot_later) { return MUST_REBOOT; } LOG(WARNING) << "No partitions to remount"; Loading Loading @@ -518,8 +538,8 @@ static int do_remount(int argc, char* argv[]) { retval = REMOUNT_FAILED; } if (reboot_later) reboot(setup_overlayfs); if (user_please_reboot_later) { if (auto_reboot) reboot(check_result.setup_overlayfs); if (check_result.reboot_later) { LOG(INFO) << "Now reboot your device for settings to take effect"; return 0; } Loading fs_mgr/include/fs_mgr_overlayfs.h +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab); bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry); bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab); bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr, bool* change = nullptr, bool force = true); Loading Loading
fs_mgr/fs_mgr_overlayfs.cpp +25 −20 Original line number Diff line number Diff line Loading @@ -85,6 +85,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 bool fs_mgr_wants_overlayfs(FstabEntry*) { return false; } Fstab fs_mgr_overlayfs_candidate_list(const Fstab&) { return {}; } Loading Loading @@ -388,26 +392,6 @@ bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overl return false; } bool fs_mgr_wants_overlayfs(FstabEntry* entry) { // Don't check entries that are managed by vold. if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false; // *_other doesn't want overlayfs. if (entry->fs_mgr_flags.slot_select_other) return false; // Only concerned with readonly partitions. if (!(entry->flags & MS_RDONLY)) return false; // If unbindable, do not allow overlayfs as this could expose us to // security issues. On Android, this could also be used to turn off // the ability to overlay an otherwise acceptable filesystem since // /system and /vendor are never bound(sic) to. if (entry->flags & MS_UNBINDABLE) return false; if (!fs_mgr_overlayfs_enabled(entry)) return false; return true; } constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0"; bool fs_mgr_overlayfs_setup_dir(const std::string& dir, std::string* overlay, bool* change) { Loading Loading @@ -1284,6 +1268,27 @@ bool fs_mgr_overlayfs_invalid() { } // namespace bool fs_mgr_wants_overlayfs(FstabEntry* entry) { // Don't check entries that are managed by vold. if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false; // *_other doesn't want overlayfs. if (entry->fs_mgr_flags.slot_select_other) return false; // Only concerned with readonly partitions. if (!(entry->flags & MS_RDONLY)) return false; // If unbindable, do not allow overlayfs as this could expose us to // security issues. On Android, this could also be used to turn off // the ability to overlay an otherwise acceptable filesystem since // /system and /vendor are never bound(sic) to. if (entry->flags & MS_UNBINDABLE) return false; if (!fs_mgr_overlayfs_enabled(entry)) return false; return true; } Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) { Fstab candidates; for (const auto& entry : fstab) { Loading
fs_mgr/fs_mgr_remount.cpp +77 −57 Original line number Diff line number Diff line Loading @@ -261,6 +261,74 @@ static RemountStatus GetRemountList(const Fstab& fstab, const std::vector<std::s return REMOUNT_SUCCESS; } struct RemountCheckResult { bool reboot_later = false; bool setup_overlayfs = false; bool disabled_verity = false; bool verity_error = false; }; static RemountStatus CheckVerity(const FstabEntry& entry, RemountCheckResult* result) { if (!fs_mgr_is_verity_enabled(entry)) { return REMOUNT_SUCCESS; } if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked") { return VERITY_PARTITION; } bool ok = false; std::unique_ptr<AvbOps, decltype(&::avb_ops_user_free)> ops(avb_ops_user_new(), &::avb_ops_user_free); if (ops) { auto suffix = android::base::GetProperty("ro.boot.slot_suffix", ""); ok = avb_user_verity_set(ops.get(), suffix.c_str(), false); } if (!ok && fs_mgr_set_blk_ro(entry.blk_device, false)) { fec::io fh(entry.blk_device.c_str(), O_RDWR); ok = fh && fh.set_verity_status(false); } if (!ok) { return VERITY_PARTITION; } result->disabled_verity = true; result->reboot_later = true; return REMOUNT_SUCCESS; } static RemountStatus CheckVerityAndOverlayfs(Fstab* partitions, RemountCheckResult* result) { RemountStatus status = REMOUNT_SUCCESS; for (auto it = partitions->begin(); it != partitions->end();) { auto& entry = *it; const auto& mount_point = entry.mount_point; if (auto rv = CheckVerity(entry, result); rv != REMOUNT_SUCCESS) { LOG(ERROR) << "Skipping verified partition " << mount_point << " for remount"; status = rv; it = partitions->erase(it); continue; } if (fs_mgr_wants_overlayfs(&entry)) { bool change = false; bool force = result->disabled_verity; if (!fs_mgr_overlayfs_setup(nullptr, mount_point.c_str(), &change, force)) { LOG(ERROR) << "Overlayfs setup for " << mount_point << " failed, skipping"; status = BAD_OVERLAY; it = partitions->erase(it); continue; } if (change) { LOG(INFO) << "Using overlayfs for " << mount_point; result->reboot_later = true; result->setup_overlayfs = true; } } it++; } return status; } static int do_remount(int argc, char* argv[]) { RemountStatus retval = REMOUNT_SUCCESS; Loading Loading @@ -342,64 +410,16 @@ static int do_remount(int argc, char* argv[]) { } // Check verity and optionally setup overlayfs backing. auto reboot_later = false; auto user_please_reboot_later = false; auto setup_overlayfs = false; auto just_disabled_verity = false; for (auto it = partitions.begin(); it != partitions.end();) { auto& entry = *it; auto& mount_point = entry.mount_point; if (fs_mgr_is_verity_enabled(entry)) { retval = VERITY_PARTITION; auto ret = false; if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") != "locked") { if (AvbOps* ops = avb_ops_user_new()) { ret = avb_user_verity_set( ops, android::base::GetProperty("ro.boot.slot_suffix", "").c_str(), false); avb_ops_user_free(ops); } if (!ret && fs_mgr_set_blk_ro(entry.blk_device, false)) { fec::io fh(entry.blk_device.c_str(), O_RDWR); ret = fh && fh.set_verity_status(false); } if (ret) { LOG(WARNING) << "Disabling verity for " << mount_point; just_disabled_verity = true; reboot_later = can_reboot; user_please_reboot_later = true; } } if (!ret) { LOG(ERROR) << "Skipping " << mount_point << " for remount"; it = partitions.erase(it); continue; } } RemountCheckResult check_result; retval = CheckVerityAndOverlayfs(&partitions, &check_result); auto change = false; errno = 0; if (fs_mgr_overlayfs_setup(nullptr, mount_point.c_str(), &change, just_disabled_verity)) { if (change) { LOG(INFO) << "Using overlayfs for " << mount_point; reboot_later = can_reboot; user_please_reboot_later = true; setup_overlayfs = true; } } else if (errno) { PLOG(ERROR) << "Overlayfs setup for " << mount_point << " failed, skipping"; retval = BAD_OVERLAY; it = partitions.erase(it); continue; } ++it; } bool auto_reboot = check_result.reboot_later && can_reboot; // If (1) remount requires a reboot to take effect, (2) system is currently // running a DSU guest and (3) DSU is disabled, then enable DSU so that the // next reboot would not take us back to the host system but stay within // the guest system. if (reboot_later) { if (auto_reboot) { if (auto gsid = android::gsi::GetGsiService()) { auto dsu_running = false; if (auto status = gsid->isGsiRunning(&dsu_running); !status.isOk()) { Loading Loading @@ -430,9 +450,9 @@ static int do_remount(int argc, char* argv[]) { } } if (partitions.empty() || just_disabled_verity) { if (reboot_later) reboot(setup_overlayfs); if (user_please_reboot_later) { if (partitions.empty() || check_result.disabled_verity) { if (auto_reboot) reboot(check_result.setup_overlayfs); if (check_result.reboot_later) { return MUST_REBOOT; } LOG(WARNING) << "No partitions to remount"; Loading Loading @@ -518,8 +538,8 @@ static int do_remount(int argc, char* argv[]) { retval = REMOUNT_FAILED; } if (reboot_later) reboot(setup_overlayfs); if (user_please_reboot_later) { if (auto_reboot) reboot(check_result.setup_overlayfs); if (check_result.reboot_later) { LOG(INFO) << "Now reboot your device for settings to take effect"; return 0; } Loading
fs_mgr/include/fs_mgr_overlayfs.h +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab); bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry); bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab); bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr, bool* change = nullptr, bool force = true); Loading