From 6a11694c1b157fc66a13f128e44e4423a5acb98b Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 5 Nov 2018 08:53:30 -0800 Subject: [PATCH] fs_mgr: overlayfs earlier kernels do not need override_creds=off Kernels at or older than 4.6, the overlayfs drivers do not need, or support, override_creds=off. Drop using the mount option. Commit 3fe6e52f062643676eb4518d68cee3bc1272091b introduced the need for override_creds=off, and none of the kernels that contain this patch without the patch that introduces override_creds can be used with Android. Test: compile Bug: 118882257 Bug: 109821005 Change-Id: I832c8ca3fce0269bdef4ce988541adb7ba9662ed --- fs_mgr/fs_mgr_overlayfs.cpp | 49 +++++++++++++++++++++++++------ fs_mgr/fs_mgr_vendor_overlay.cpp | 8 +++-- fs_mgr/include/fs_mgr_overlayfs.h | 8 ++++- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index 49ecc06a2..a1de005a5 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -56,13 +57,17 @@ using namespace std::literals; using namespace android::dm; using namespace android::fs_mgr; -static bool fs_mgr_access(const std::string& path) { +namespace { + +bool fs_mgr_access(const std::string& path) { auto save_errno = errno; auto ret = access(path.c_str(), F_OK) == 0; errno = save_errno; return ret; } +} // namespace + #if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs bool fs_mgr_overlayfs_mount_all(fstab*) { @@ -218,9 +223,12 @@ const auto kUpperdirOption = "upperdir="s; std::string fs_mgr_get_overlayfs_options(const std::string& mount_point) { auto candidate = fs_mgr_get_overlayfs_candidate(mount_point); if (candidate.empty()) return ""; - - return "override_creds=off," + kLowerdirOption + mount_point + "," + kUpperdirOption + - candidate + kUpperName + ",workdir=" + candidate + kWorkName; + auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName + + ",workdir=" + candidate + kWorkName; + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) { + ret += ",override_creds=off"; + } + return ret; } const char* fs_mgr_mount_point(const char* mount_point) { @@ -733,7 +741,7 @@ bool fs_mgr_overlayfs_scratch_can_be_mounted(const std::string& scratch_device) bool fs_mgr_overlayfs_mount_all(fstab* fstab) { auto ret = false; - if (!fs_mgr_overlayfs_supports_override_creds()) return ret; + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return ret; if (!fstab) return ret; @@ -791,7 +799,7 @@ std::vector fs_mgr_overlayfs_required_devices( bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* change) { if (change) *change = false; auto ret = false; - if (!fs_mgr_overlayfs_supports_override_creds()) return ret; + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return ret; if (!fs_mgr_boot_completed()) { errno = EBUSY; PERROR << "setup"; @@ -854,7 +862,7 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { for (const auto& overlay_mount_point : kOverlayMountPoints) { ret &= fs_mgr_overlayfs_teardown_one(overlay_mount_point, mount_point ?: "", change); } - if (!fs_mgr_overlayfs_supports_override_creds()) { + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { // After obligatory teardown to make sure everything is clean, but if // we didn't want overlayfs in the the first place, we do not want to // waste time on a reboot (or reboot request message). @@ -905,7 +913,30 @@ std::string fs_mgr_get_context(const std::string& mount_point) { return context; } -bool fs_mgr_overlayfs_supports_override_creds() { +OverlayfsValidResult fs_mgr_overlayfs_valid() { // Overlayfs available in the kernel, and patched for override_creds? - return fs_mgr_access("/sys/module/overlay/parameters/override_creds"); + if (fs_mgr_access("/sys/module/overlay/parameters/override_creds")) { + return OverlayfsValidResult::kOverrideCredsRequired; + } + if (!fs_mgr_access("/sys/module/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 > 6) { + return OverlayfsValidResult::kNotSupported; + } + return OverlayfsValidResult::kOk; } diff --git a/fs_mgr/fs_mgr_vendor_overlay.cpp b/fs_mgr/fs_mgr_vendor_overlay.cpp index a9a69cd7a..e1815ffc6 100644 --- a/fs_mgr/fs_mgr_vendor_overlay.cpp +++ b/fs_mgr/fs_mgr_vendor_overlay.cpp @@ -87,8 +87,10 @@ bool fs_mgr_vendor_overlay_mount(const std::string& overlay_top, const std::stri return false; } - auto options = - "override_creds=off,"s + kLowerdirOption + source_directory + ":" + vendor_mount_point; + auto options = kLowerdirOption + source_directory + ":" + vendor_mount_point; + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) { + options += ",override_creds=off"; + } auto report = "__mount(source=overlay,target="s + vendor_mount_point + ",type=overlay," + options + ")="; auto ret = mount("overlay", vendor_mount_point.c_str(), "overlay", MS_RDONLY | MS_RELATIME, @@ -117,7 +119,7 @@ bool fs_mgr_vendor_overlay_mount_all() { } const auto vendor_overlay_dirs = fs_mgr_get_vendor_overlay_dirs(overlay_top); if (vendor_overlay_dirs.empty()) return true; - if (!fs_mgr_overlayfs_supports_override_creds()) { + if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) { LINFO << "vendor overlay: kernel does not support overlayfs"; return false; } diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h index 72202ab30..deaf4cb1c 100644 --- a/fs_mgr/include/fs_mgr_overlayfs.h +++ b/fs_mgr/include/fs_mgr_overlayfs.h @@ -31,4 +31,10 @@ bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_poi bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr); bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev); std::string fs_mgr_get_context(const std::string& mount_point); -bool fs_mgr_overlayfs_supports_override_creds(); + +enum class OverlayfsValidResult { + kNotSupported = 0, + kOk, + kOverrideCredsRequired, +}; +OverlayfsValidResult fs_mgr_overlayfs_valid();