Merge "fs_mgr: overlayfs earlier kernels do not need override_creds=off"

This commit is contained in:
Treehugger Robot 2018-11-07 20:51:07 +00:00 committed by Gerrit Code Review
commit 71c29a9ce0
3 changed files with 52 additions and 13 deletions

View file

@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/vfs.h>
#include <unistd.h>
@ -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<std::string> 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;
}

View file

@ -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;
}

View file

@ -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();