Loading fs_mgr/Android.bp +36 −0 Original line number Diff line number Diff line Loading @@ -254,3 +254,39 @@ cc_binary { "clean_scratch_files", ], } cc_binary { name: "set-verity-state", srcs: ["set-verity-state.cpp"], shared_libs: [ "libbase", "libbinder", "libcrypto", "libcrypto_utils", "libfs_mgr_binder", "libutils", ], static_libs: [ "libavb_user", ], header_libs: [ "libcutils_headers", ], cflags: ["-Werror"], cppflags: [ "-DALLOW_DISABLE_VERITY=0", ], product_variables: { debuggable: { cppflags: [ "-UALLOW_DISABLE_VERITY", "-DALLOW_DISABLE_VERITY=1", ], }, }, symlinks: [ "enable-verity", "disable-verity", ], } fs_mgr/OWNERS +1 −0 Original line number Diff line number Diff line Loading @@ -2,3 +2,4 @@ bowgotsai@google.com dvander@google.com elsk@google.com yochiang@google.com fs_mgr/fs_mgr.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <fcntl.h> #include <inttypes.h> #include <libgen.h> #include <selinux/selinux.h> #include <stdio.h> #include <stdlib.h> #include <string.h> Loading @@ -30,6 +31,7 @@ #include <sys/stat.h> #include <sys/swap.h> #include <sys/types.h> #include <sys/utsname.h> #include <sys/wait.h> #include <time.h> #include <unistd.h> Loading Loading @@ -2359,3 +2361,49 @@ bool fs_mgr_load_verity_state(int* mode) { return true; } bool fs_mgr_filesystem_available(const std::string& filesystem) { std::string filesystems; if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false; return filesystems.find("\t" + filesystem + "\n") != std::string::npos; } std::string fs_mgr_get_context(const std::string& mount_point) { char* ctx = nullptr; if (getfilecon(mount_point.c_str(), &ctx) == -1) { PERROR << "getfilecon " << mount_point; return ""; } std::string context(ctx); free(ctx); return context; } OverlayfsValidResult fs_mgr_overlayfs_valid() { // Overlayfs available in the kernel, and patched for override_creds? if (access("/sys/module/overlay/parameters/override_creds", F_OK) == 0) { return OverlayfsValidResult::kOverrideCredsRequired; } if (!fs_mgr_filesystem_available("overlay")) { return OverlayfsValidResult::kNotSupported; } struct utsname uts; if (uname(&uts) == -1) { return OverlayfsValidResult::kNotSupported; } int major, minor; if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) { return OverlayfsValidResult::kNotSupported; } if (major < 4) { return OverlayfsValidResult::kOk; } if (major > 4) { return OverlayfsValidResult::kNotSupported; } if (minor > 3) { return OverlayfsValidResult::kNotSupported; } return OverlayfsValidResult::kOk; } fs_mgr/fs_mgr_overlayfs.cpp +76 −128 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ #include <storage_literals/storage_literals.h> #include "fs_mgr_priv.h" #include "fs_mgr_priv_overlayfs.h" #include "libfiemap/utility.h" using namespace std::literals; Loading @@ -71,62 +72,9 @@ bool fs_mgr_access(const std::string& path) { return access(path.c_str(), F_OK) == 0; } // determine if a filesystem is available bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) { std::string filesystems; if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false; return filesystems.find("\t" + filesystem + "\n") != std::string::npos; } const auto kLowerdirOption = "lowerdir="s; const auto kUpperdirOption = "upperdir="s; } // namespace #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 {}; } bool fs_mgr_overlayfs_mount_all(Fstab*) { return false; } bool fs_mgr_overlayfs_setup(const char*, bool*, bool) { LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds"; return false; } OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char*, bool*) { return OverlayfsTeardownResult::Ok; } bool fs_mgr_overlayfs_is_setup() { return false; } namespace android { namespace fs_mgr { void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) { } void CleanupOldScratchFiles() {} void TeardownAllOverlayForMountPoint(const std::string&) {} } // namespace fs_mgr } // namespace android #else // ALLOW_ADBD_DISABLE_VERITY == 0 namespace { bool fs_mgr_in_recovery() { // Check the existence of recovery binary instead of using the compile time // __ANDROID_RECOVERY__ macro. Loading Loading @@ -234,6 +182,28 @@ bool fs_mgr_update_blk_device(FstabEntry* entry) { return true; } bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) { struct statfs fs; if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) || (fs.f_type != EXT4_SUPER_MAGIC)) { return false; } android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC)); if (fd < 0) return false; struct ext4_super_block sb; if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) || (TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) { return false; } struct fs_info info; if (ext4_parse_sb(&sb, &info) < 0) return false; return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0; } bool fs_mgr_overlayfs_enabled(FstabEntry* entry) { // readonly filesystem, can not be mount -o remount,rw // for squashfs, erofs or if free space is (near) zero making such a remount Loading Loading @@ -886,10 +856,10 @@ const std::string kMkExt4("/system/bin/mke2fs"); // Only a suggestion for _first_ try during mounting std::string fs_mgr_overlayfs_scratch_mount_type() { if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("f2fs")) { if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) { return "f2fs"; } if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("ext4")) { if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) { return "ext4"; } return "auto"; Loading Loading @@ -1233,11 +1203,41 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) { return fs_mgr_overlayfs_mount_scratch(scratch_device, mnt_type); } bool fs_mgr_overlayfs_invalid() { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true; #if ALLOW_ADBD_DISABLE_VERITY constexpr bool kAllowOverlayfs = true; #else constexpr bool kAllowOverlayfs = false; #endif // NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed(). // Setup is allowed only if teardown is also allowed. bool OverlayfsSetupAllowed(bool verbose = false) { if (!kAllowOverlayfs) { if (verbose) { LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds"; } return false; } // Check mandatory kernel patches. if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { if (verbose) { LOG(ERROR) << "Kernel does not support overlayfs"; } return false; } // in recovery or fastbootd, not allowed! return fs_mgr_in_recovery(); if (fs_mgr_in_recovery()) { if (verbose) { LOG(ERROR) << "Unsupported overlayfs setup from recovery"; } return false; } return true; } constexpr bool OverlayfsTeardownAllowed() { // Never allow on non-debuggable build. return kAllowOverlayfs; } } // namespace Loading Loading @@ -1331,7 +1331,7 @@ static void TryMountScratch() { } bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { if (fs_mgr_overlayfs_invalid()) { if (!OverlayfsSetupAllowed()) { return false; } auto ret = true; Loading @@ -1352,8 +1352,7 @@ bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { } bool fs_mgr_overlayfs_setup(const char* mount_point, bool* want_reboot, bool just_disabled_verity) { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { LOG(ERROR) << "Overlayfs is not supported"; if (!OverlayfsSetupAllowed(/*verbose=*/true)) { return false; } Loading Loading @@ -1523,7 +1522,8 @@ static bool MapDsuScratchDevice(std::string* device) { return true; } OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* want_reboot) { static OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* want_reboot) { bool should_destroy_scratch = false; auto rv = OverlayfsTeardownResult::Ok; for (const auto& overlay_mount_point : OverlayMountPoints()) { Loading Loading @@ -1555,6 +1555,10 @@ OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* // Returns false if teardown not permitted. If something is altered, set *want_reboot. OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* want_reboot) { if (!OverlayfsTeardownAllowed()) { // Nothing to teardown. return OverlayfsTeardownResult::Ok; } // If scratch exists, but is not mounted, lets gain access to clean // specific override entries. auto mount_scratch = false; Loading @@ -1577,12 +1581,14 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* } bool fs_mgr_overlayfs_is_setup() { if (!OverlayfsSetupAllowed()) { return false; } if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true; Fstab fstab; if (!ReadDefaultFstab(&fstab)) { return false; } if (fs_mgr_overlayfs_invalid()) return false; 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; Loading @@ -1595,7 +1601,7 @@ namespace fs_mgr { void MapScratchPartitionIfNeeded(Fstab* fstab, const std::function<bool(const std::set<std::string>&)>& init) { if (fs_mgr_overlayfs_invalid()) { if (!OverlayfsSetupAllowed()) { return; } if (GetEntryForMountPoint(fstab, kScratchMountPoint) != nullptr) { Loading Loading @@ -1632,6 +1638,9 @@ void MapScratchPartitionIfNeeded(Fstab* fstab, } void CleanupOldScratchFiles() { if (!OverlayfsTeardownAllowed()) { return; } if (!ScratchIsOnData()) { return; } Loading @@ -1641,6 +1650,9 @@ void CleanupOldScratchFiles() { } void TeardownAllOverlayForMountPoint(const std::string& mount_point) { if (!OverlayfsTeardownAllowed()) { return; } if (!fs_mgr_in_recovery()) { LERROR << __FUNCTION__ << "(): must be called within recovery."; return; Loading Loading @@ -1701,8 +1713,6 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) { } // namespace fs_mgr } // namespace android #endif // ALLOW_ADBD_DISABLE_VERITY != 0 bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only) { Fstab fstab; if (!ReadFstabFromFile("/proc/mounts", &fstab)) { Loading @@ -1722,65 +1732,3 @@ bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overl } return false; } bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) { struct statfs fs; if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) || (fs.f_type != EXT4_SUPER_MAGIC)) { return false; } android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC)); if (fd < 0) return false; struct ext4_super_block sb; if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) || (TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) { return false; } struct fs_info info; if (ext4_parse_sb(&sb, &info) < 0) return false; return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0; } std::string fs_mgr_get_context(const std::string& mount_point) { char* ctx = nullptr; if (getfilecon(mount_point.c_str(), &ctx) == -1) { PLOG(ERROR) << "getfilecon " << mount_point; return ""; } std::string context(ctx); free(ctx); return context; } OverlayfsValidResult fs_mgr_overlayfs_valid() { // Overlayfs available in the kernel, and patched for override_creds? if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) { return OverlayfsValidResult::kOverrideCredsRequired; } if (!fs_mgr_overlayfs_filesystem_available("overlay")) { return OverlayfsValidResult::kNotSupported; } struct utsname uts; if (uname(&uts) == -1) { return OverlayfsValidResult::kNotSupported; } int major, minor; if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) { return OverlayfsValidResult::kNotSupported; } if (major < 4) { return OverlayfsValidResult::kOk; } if (major > 4) { return OverlayfsValidResult::kNotSupported; } if (minor > 3) { return OverlayfsValidResult::kNotSupported; } return OverlayfsValidResult::kOk; } fs_mgr/fs_mgr_priv.h +10 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,16 @@ bool fs_mgr_is_f2fs(const std::string& blk_device); bool fs_mgr_teardown_verity(android::fs_mgr::FstabEntry* fstab); bool fs_mgr_filesystem_available(const std::string& filesystem); std::string fs_mgr_get_context(const std::string& mount_point); enum class OverlayfsValidResult { kNotSupported = 0, kOk, kOverrideCredsRequired, }; OverlayfsValidResult fs_mgr_overlayfs_valid(); namespace android { namespace fs_mgr { bool UnmapDevice(const std::string& name); Loading Loading
fs_mgr/Android.bp +36 −0 Original line number Diff line number Diff line Loading @@ -254,3 +254,39 @@ cc_binary { "clean_scratch_files", ], } cc_binary { name: "set-verity-state", srcs: ["set-verity-state.cpp"], shared_libs: [ "libbase", "libbinder", "libcrypto", "libcrypto_utils", "libfs_mgr_binder", "libutils", ], static_libs: [ "libavb_user", ], header_libs: [ "libcutils_headers", ], cflags: ["-Werror"], cppflags: [ "-DALLOW_DISABLE_VERITY=0", ], product_variables: { debuggable: { cppflags: [ "-UALLOW_DISABLE_VERITY", "-DALLOW_DISABLE_VERITY=1", ], }, }, symlinks: [ "enable-verity", "disable-verity", ], }
fs_mgr/OWNERS +1 −0 Original line number Diff line number Diff line Loading @@ -2,3 +2,4 @@ bowgotsai@google.com dvander@google.com elsk@google.com yochiang@google.com
fs_mgr/fs_mgr.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <fcntl.h> #include <inttypes.h> #include <libgen.h> #include <selinux/selinux.h> #include <stdio.h> #include <stdlib.h> #include <string.h> Loading @@ -30,6 +31,7 @@ #include <sys/stat.h> #include <sys/swap.h> #include <sys/types.h> #include <sys/utsname.h> #include <sys/wait.h> #include <time.h> #include <unistd.h> Loading Loading @@ -2359,3 +2361,49 @@ bool fs_mgr_load_verity_state(int* mode) { return true; } bool fs_mgr_filesystem_available(const std::string& filesystem) { std::string filesystems; if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false; return filesystems.find("\t" + filesystem + "\n") != std::string::npos; } std::string fs_mgr_get_context(const std::string& mount_point) { char* ctx = nullptr; if (getfilecon(mount_point.c_str(), &ctx) == -1) { PERROR << "getfilecon " << mount_point; return ""; } std::string context(ctx); free(ctx); return context; } OverlayfsValidResult fs_mgr_overlayfs_valid() { // Overlayfs available in the kernel, and patched for override_creds? if (access("/sys/module/overlay/parameters/override_creds", F_OK) == 0) { return OverlayfsValidResult::kOverrideCredsRequired; } if (!fs_mgr_filesystem_available("overlay")) { return OverlayfsValidResult::kNotSupported; } struct utsname uts; if (uname(&uts) == -1) { return OverlayfsValidResult::kNotSupported; } int major, minor; if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) { return OverlayfsValidResult::kNotSupported; } if (major < 4) { return OverlayfsValidResult::kOk; } if (major > 4) { return OverlayfsValidResult::kNotSupported; } if (minor > 3) { return OverlayfsValidResult::kNotSupported; } return OverlayfsValidResult::kOk; }
fs_mgr/fs_mgr_overlayfs.cpp +76 −128 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ #include <storage_literals/storage_literals.h> #include "fs_mgr_priv.h" #include "fs_mgr_priv_overlayfs.h" #include "libfiemap/utility.h" using namespace std::literals; Loading @@ -71,62 +72,9 @@ bool fs_mgr_access(const std::string& path) { return access(path.c_str(), F_OK) == 0; } // determine if a filesystem is available bool fs_mgr_overlayfs_filesystem_available(const std::string& filesystem) { std::string filesystems; if (!android::base::ReadFileToString("/proc/filesystems", &filesystems)) return false; return filesystems.find("\t" + filesystem + "\n") != std::string::npos; } const auto kLowerdirOption = "lowerdir="s; const auto kUpperdirOption = "upperdir="s; } // namespace #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 {}; } bool fs_mgr_overlayfs_mount_all(Fstab*) { return false; } bool fs_mgr_overlayfs_setup(const char*, bool*, bool) { LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds"; return false; } OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char*, bool*) { return OverlayfsTeardownResult::Ok; } bool fs_mgr_overlayfs_is_setup() { return false; } namespace android { namespace fs_mgr { void MapScratchPartitionIfNeeded(Fstab*, const std::function<bool(const std::set<std::string>&)>&) { } void CleanupOldScratchFiles() {} void TeardownAllOverlayForMountPoint(const std::string&) {} } // namespace fs_mgr } // namespace android #else // ALLOW_ADBD_DISABLE_VERITY == 0 namespace { bool fs_mgr_in_recovery() { // Check the existence of recovery binary instead of using the compile time // __ANDROID_RECOVERY__ macro. Loading Loading @@ -234,6 +182,28 @@ bool fs_mgr_update_blk_device(FstabEntry* entry) { return true; } bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) { struct statfs fs; if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) || (fs.f_type != EXT4_SUPER_MAGIC)) { return false; } android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC)); if (fd < 0) return false; struct ext4_super_block sb; if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) || (TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) { return false; } struct fs_info info; if (ext4_parse_sb(&sb, &info) < 0) return false; return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0; } bool fs_mgr_overlayfs_enabled(FstabEntry* entry) { // readonly filesystem, can not be mount -o remount,rw // for squashfs, erofs or if free space is (near) zero making such a remount Loading Loading @@ -886,10 +856,10 @@ const std::string kMkExt4("/system/bin/mke2fs"); // Only a suggestion for _first_ try during mounting std::string fs_mgr_overlayfs_scratch_mount_type() { if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("f2fs")) { if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) { return "f2fs"; } if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_overlayfs_filesystem_available("ext4")) { if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) { return "ext4"; } return "auto"; Loading Loading @@ -1233,11 +1203,41 @@ bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab) { return fs_mgr_overlayfs_mount_scratch(scratch_device, mnt_type); } bool fs_mgr_overlayfs_invalid() { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true; #if ALLOW_ADBD_DISABLE_VERITY constexpr bool kAllowOverlayfs = true; #else constexpr bool kAllowOverlayfs = false; #endif // NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed(). // Setup is allowed only if teardown is also allowed. bool OverlayfsSetupAllowed(bool verbose = false) { if (!kAllowOverlayfs) { if (verbose) { LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds"; } return false; } // Check mandatory kernel patches. if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { if (verbose) { LOG(ERROR) << "Kernel does not support overlayfs"; } return false; } // in recovery or fastbootd, not allowed! return fs_mgr_in_recovery(); if (fs_mgr_in_recovery()) { if (verbose) { LOG(ERROR) << "Unsupported overlayfs setup from recovery"; } return false; } return true; } constexpr bool OverlayfsTeardownAllowed() { // Never allow on non-debuggable build. return kAllowOverlayfs; } } // namespace Loading Loading @@ -1331,7 +1331,7 @@ static void TryMountScratch() { } bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { if (fs_mgr_overlayfs_invalid()) { if (!OverlayfsSetupAllowed()) { return false; } auto ret = true; Loading @@ -1352,8 +1352,7 @@ bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { } bool fs_mgr_overlayfs_setup(const char* mount_point, bool* want_reboot, bool just_disabled_verity) { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { LOG(ERROR) << "Overlayfs is not supported"; if (!OverlayfsSetupAllowed(/*verbose=*/true)) { return false; } Loading Loading @@ -1523,7 +1522,8 @@ static bool MapDsuScratchDevice(std::string* device) { return true; } OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* want_reboot) { static OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* want_reboot) { bool should_destroy_scratch = false; auto rv = OverlayfsTeardownResult::Ok; for (const auto& overlay_mount_point : OverlayMountPoints()) { Loading Loading @@ -1555,6 +1555,10 @@ OverlayfsTeardownResult TeardownMountsAndScratch(const char* mount_point, bool* // Returns false if teardown not permitted. If something is altered, set *want_reboot. OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* want_reboot) { if (!OverlayfsTeardownAllowed()) { // Nothing to teardown. return OverlayfsTeardownResult::Ok; } // If scratch exists, but is not mounted, lets gain access to clean // specific override entries. auto mount_scratch = false; Loading @@ -1577,12 +1581,14 @@ OverlayfsTeardownResult fs_mgr_overlayfs_teardown(const char* mount_point, bool* } bool fs_mgr_overlayfs_is_setup() { if (!OverlayfsSetupAllowed()) { return false; } if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true; Fstab fstab; if (!ReadDefaultFstab(&fstab)) { return false; } if (fs_mgr_overlayfs_invalid()) return false; 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; Loading @@ -1595,7 +1601,7 @@ namespace fs_mgr { void MapScratchPartitionIfNeeded(Fstab* fstab, const std::function<bool(const std::set<std::string>&)>& init) { if (fs_mgr_overlayfs_invalid()) { if (!OverlayfsSetupAllowed()) { return; } if (GetEntryForMountPoint(fstab, kScratchMountPoint) != nullptr) { Loading Loading @@ -1632,6 +1638,9 @@ void MapScratchPartitionIfNeeded(Fstab* fstab, } void CleanupOldScratchFiles() { if (!OverlayfsTeardownAllowed()) { return; } if (!ScratchIsOnData()) { return; } Loading @@ -1641,6 +1650,9 @@ void CleanupOldScratchFiles() { } void TeardownAllOverlayForMountPoint(const std::string& mount_point) { if (!OverlayfsTeardownAllowed()) { return; } if (!fs_mgr_in_recovery()) { LERROR << __FUNCTION__ << "(): must be called within recovery."; return; Loading Loading @@ -1701,8 +1713,6 @@ void TeardownAllOverlayForMountPoint(const std::string& mount_point) { } // namespace fs_mgr } // namespace android #endif // ALLOW_ADBD_DISABLE_VERITY != 0 bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only) { Fstab fstab; if (!ReadFstabFromFile("/proc/mounts", &fstab)) { Loading @@ -1722,65 +1732,3 @@ bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overl } return false; } bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) { struct statfs fs; if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) || (fs.f_type != EXT4_SUPER_MAGIC)) { return false; } android::base::unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC)); if (fd < 0) return false; struct ext4_super_block sb; if ((TEMP_FAILURE_RETRY(lseek64(fd, 1024, SEEK_SET)) < 0) || (TEMP_FAILURE_RETRY(read(fd, &sb, sizeof(sb))) < 0)) { return false; } struct fs_info info; if (ext4_parse_sb(&sb, &info) < 0) return false; return (info.feat_ro_compat & EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS) != 0; } std::string fs_mgr_get_context(const std::string& mount_point) { char* ctx = nullptr; if (getfilecon(mount_point.c_str(), &ctx) == -1) { PLOG(ERROR) << "getfilecon " << mount_point; return ""; } std::string context(ctx); free(ctx); return context; } OverlayfsValidResult fs_mgr_overlayfs_valid() { // Overlayfs available in the kernel, and patched for override_creds? if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) { return OverlayfsValidResult::kOverrideCredsRequired; } if (!fs_mgr_overlayfs_filesystem_available("overlay")) { return OverlayfsValidResult::kNotSupported; } struct utsname uts; if (uname(&uts) == -1) { return OverlayfsValidResult::kNotSupported; } int major, minor; if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) { return OverlayfsValidResult::kNotSupported; } if (major < 4) { return OverlayfsValidResult::kOk; } if (major > 4) { return OverlayfsValidResult::kNotSupported; } if (minor > 3) { return OverlayfsValidResult::kNotSupported; } return OverlayfsValidResult::kOk; }
fs_mgr/fs_mgr_priv.h +10 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,16 @@ bool fs_mgr_is_f2fs(const std::string& blk_device); bool fs_mgr_teardown_verity(android::fs_mgr::FstabEntry* fstab); bool fs_mgr_filesystem_available(const std::string& filesystem); std::string fs_mgr_get_context(const std::string& mount_point); enum class OverlayfsValidResult { kNotSupported = 0, kOk, kOverrideCredsRequired, }; OverlayfsValidResult fs_mgr_overlayfs_valid(); namespace android { namespace fs_mgr { bool UnmapDevice(const std::string& name); Loading