Make fs_mgr_overlayfs_mount_fstab_entry() available for user builds
Rename fs_mgr_overlayfs_mount_fstab_entry() to
fs_mgr_mount_overlayfs_fstab_entry() and move it out of
fs_mgr_overlayfs.cpp to make it available for user builds.
Add checks to unsure overlayfs mount point doesn't contain symbolic
link or /../.
Check the mount point with an allowlist if user build. The mount point
should either be /vendor, /product ... or their submounts, or strict
submounts of /mnt/vendor and /mnt/product.
Bug: 188862155
Test: Boot test with overlayfs mount entries on user build
Change-Id: I3b60dfa4b63cf2ae0754f53d1d08365aa7be1ee0
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index ea9d333..08ead7a 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2265,3 +2265,72 @@
}
return LP_METADATA_DEFAULT_PARTITION_NAME;
}
+
+bool fs_mgr_mount_overlayfs_fstab_entry(const FstabEntry& entry) {
+ auto overlayfs_valid_result = fs_mgr_overlayfs_valid();
+ if (overlayfs_valid_result == OverlayfsValidResult::kNotSupported) {
+ LERROR << __FUNCTION__ << "(): kernel does not support overlayfs";
+ return false;
+ }
+
+#if ALLOW_ADBD_DISABLE_VERITY == 0
+ // Allowlist the mount point if user build.
+ static const std::vector<const std::string> kAllowedPaths = {
+ "/odm", "/odm_dlkm", "/oem", "/product", "/system_ext", "/vendor", "/vendor_dlkm",
+ };
+ static const std::vector<const std::string> kAllowedPrefixes = {
+ "/mnt/product/",
+ "/mnt/vendor/",
+ };
+ if (std::none_of(kAllowedPaths.begin(), kAllowedPaths.end(),
+ [&entry](const auto& path) -> bool {
+ return entry.mount_point == path ||
+ StartsWith(entry.mount_point, path + "/");
+ }) &&
+ std::none_of(kAllowedPrefixes.begin(), kAllowedPrefixes.end(),
+ [&entry](const auto& prefix) -> bool {
+ return entry.mount_point != prefix &&
+ StartsWith(entry.mount_point, prefix);
+ })) {
+ LERROR << __FUNCTION__
+ << "(): mount point is forbidden on user build: " << entry.mount_point;
+ return false;
+ }
+#endif // ALLOW_ADBD_DISABLE_VERITY == 0
+
+ // Create the mount point in case it doesn't exist.
+ mkdir(entry.mount_point.c_str(), 0755);
+
+ // Ensure that mount point exists and doesn't contain symbolic link or /../.
+ std::string mount_point;
+ if (!Realpath(entry.mount_point, &mount_point)) {
+ PERROR << __FUNCTION__ << "(): failed to realpath " << entry.mount_point;
+ return false;
+ }
+ if (entry.mount_point != mount_point) {
+ LERROR << __FUNCTION__ << "(): mount point must be a canonicalized path: realpath "
+ << entry.mount_point << " = " << mount_point;
+ return false;
+ }
+
+ auto options = "lowerdir=" + entry.lowerdir;
+ if (overlayfs_valid_result == OverlayfsValidResult::kOverrideCredsRequired) {
+ options += ",override_creds=off";
+ }
+
+ // Use "overlay-" + entry.blk_device as the mount() source, so that adb-remout-test don't
+ // confuse this with adb remount overlay, whose device name is "overlay".
+ // Overlayfs is a pseudo filesystem, so the source device is a symbolic value and isn't used to
+ // back the filesystem. However the device name would be shown in /proc/mounts.
+ auto source = "overlay-" + entry.blk_device;
+ auto report = "__mount(source=" + source + ",target=" + entry.mount_point + ",type=overlay," +
+ options + ")=";
+ auto ret = mount(source.c_str(), entry.mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
+ options.c_str());
+ if (ret) {
+ PERROR << report << ret;
+ return false;
+ }
+ LINFO << report << ret;
+ return true;
+}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 9fb658e..cb09383 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -92,10 +92,6 @@
return false;
}
-bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry&) {
- return false;
-}
-
std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab*) {
return {};
}
@@ -1299,34 +1295,6 @@
}
}
-bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry& entry) {
- if (fs_mgr_overlayfs_invalid()) return false;
-
- // Create the mount point in case it doesn't exist.
- mkdir(entry.mount_point.c_str(), 0755);
-
- auto options = kLowerdirOption + entry.lowerdir;
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
- options += ",override_creds=off";
- }
-
- // Use "overlay-" + entry.blk_device as the mount() source, so that adb-remout-test don't
- // confuse this with adb remount overlay, whose device name is "overlay".
- // Overlayfs is a pseudo filesystem, so the source device is a symbolic value and isn't used to
- // back the filesystem. However the device name would be shown in /proc/mounts.
- auto source = "overlay-" + entry.blk_device;
- auto report = "__mount(source=" + source + ",target=" + entry.mount_point + ",type=overlay," +
- options + ")=";
- auto ret = mount(source.c_str(), entry.mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
- options.c_str());
- if (ret) {
- PERROR << report << ret;
- return false;
- }
- LINFO << report << ret;
- return true;
-}
-
bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
auto ret = false;
if (fs_mgr_overlayfs_invalid()) return ret;
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 22c02cc..b8ebd63 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -131,3 +131,8 @@
// Finds the dm_bow device on which this block device is stacked, or returns
// empty string
std::string fs_mgr_find_bow_device(const std::string& block_device);
+
+// Like fs_mgr_do_mount_one() but for overlayfs fstab entries.
+// Unlike fs_mgr_overlayfs, mount overlayfs without upperdir and workdir, so the
+// filesystem cannot be remount read-write.
+bool fs_mgr_mount_overlayfs_fstab_entry(const android::fs_mgr::FstabEntry& entry);
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index 22d12e7..d45e2de 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -27,7 +27,6 @@
android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
-bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry& entry);
std::vector<std::string> fs_mgr_overlayfs_required_devices(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);
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 616d285..546ea8e 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -574,7 +574,7 @@
for (const auto& entry : fstab_) {
if (entry.fs_type == "overlay") {
- fs_mgr_overlayfs_mount_fstab_entry(entry);
+ fs_mgr_mount_overlayfs_fstab_entry(entry);
}
}