Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9032b39e authored by Yi-Yo Chiang's avatar Yi-Yo Chiang
Browse files

fs_mgr_overlayfs: Setup remount scratch dir with encoded mountpoint name

Instead of using the basename(mounpoint) as partition scratch dir name,
which could lead to name collision, use the normalized and encoded
mountpoint as scratch dir name.

Bug: 243503963
Bug: 306124139
Test: adb-remount-test
Change-Id: I5a64f17bc3b88f0ce42bd0c5779c8dd23a07917f
parent 3aee7196
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -144,7 +144,8 @@ bool fs_mgr_overlayfs_setup_one(const std::string& overlay, const std::string& m
    if (fs_mgr_overlayfs_already_mounted(mount_point)) {
        return true;
    }
    auto fsrec_mount_point = overlay + "/" + android::base::Basename(mount_point) + "/";
    const auto base = GetEncodedBaseDirForMountPoint(mount_point);
    auto fsrec_mount_point = overlay + "/" + base + "/";

    AutoSetFsCreateCon createcon(kOverlayfsFileContext);
    if (!createcon.Ok()) {
@@ -286,10 +287,10 @@ bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string
    }

    auto cleanup_all = mount_point.empty();
    const auto partition_name = android::base::Basename(mount_point);
    const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
    const auto base = GetEncodedBaseDirForMountPoint(mount_point);
    const auto oldpath = top + (cleanup_all ? "" : ("/" + base));
    const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir + ".teardown"
                                     : top + "/." + partition_name + ".teardown";
                                     : top + "/." + base + ".teardown";
    auto ret = fs_mgr_rm_all(newpath);
    if (!rename(oldpath.c_str(), newpath.c_str())) {
        if (change) *change = true;
+31 −23
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ constexpr char kPhysicalDevice[] = "/dev/block/by-name/";

constexpr char kLowerdirOption[] = "lowerdir=";
constexpr char kUpperdirOption[] = "upperdir=";
constexpr char kWorkdirOption[] = "workdir=";

bool fs_mgr_is_dsu_running() {
    // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
@@ -89,6 +90,14 @@ std::vector<const std::string> OverlayMountPoints() {
    return {kScratchMountPoint, kCacheMountPoint};
}

std::string GetEncodedBaseDirForMountPoint(const std::string& mount_point) {
    std::string normalized_path;
    if (mount_point.empty() || !android::base::Realpath(mount_point, &normalized_path)) {
        return "";
    }
    return android::base::StringReplace(normalized_path, "/", "@", true);
}

static bool fs_mgr_is_dir(const std::string& path) {
    struct stat st;
    return !stat(path.c_str(), &st) && S_ISDIR(st.st_mode);
@@ -202,21 +211,6 @@ static bool fs_mgr_overlayfs_enabled(FstabEntry* entry) {
    return has_shared_blocks;
}

static std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) {
    if (!fs_mgr_is_dir(mount_point)) return "";
    const auto base = android::base::Basename(mount_point) + "/";
    for (const auto& overlay_mount_point : OverlayMountPoints()) {
        auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base;
        auto upper = dir + kUpperName;
        if (!fs_mgr_is_dir(upper)) continue;
        auto work = dir + kWorkName;
        if (!fs_mgr_is_dir(work)) continue;
        if (access(work.c_str(), R_OK | W_OK)) continue;
        return dir;
    }
    return "";
}

const std::string fs_mgr_mount_point(const std::string& mount_point) {
    if ("/"s != mount_point) return mount_point;
    return "/system";
@@ -225,10 +219,22 @@ const std::string fs_mgr_mount_point(const std::string& mount_point) {
// default options for mount_point, returns empty string for none available.
static std::string fs_mgr_get_overlayfs_options(const FstabEntry& entry) {
    const auto mount_point = fs_mgr_mount_point(entry.mount_point);
    auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
    if (candidate.empty()) return "";
    auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName +
               ",workdir=" + candidate + kWorkName + android::fs_mgr::CheckOverlayfs().mount_flags;
    if (!fs_mgr_is_dir(mount_point)) {
        return "";
    }
    const auto base = GetEncodedBaseDirForMountPoint(mount_point);
    if (base.empty()) {
        return "";
    }
    for (const auto& overlay_mount_point : OverlayMountPoints()) {
        const auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base + "/";
        const auto upper = dir + kUpperName;
        const auto work = dir + kWorkName;
        if (!fs_mgr_is_dir(upper) || !fs_mgr_is_dir(work) || access(work.c_str(), R_OK | W_OK)) {
            continue;
        }
        auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + upper + "," +
                   kWorkdirOption + work + android::fs_mgr::CheckOverlayfs().mount_flags;
        for (const auto& flag : android::base::Split(entry.fs_options, ",")) {
            if (android::base::StartsWith(flag, "context=")) {
                ret += "," + flag;
@@ -236,6 +242,8 @@ static std::string fs_mgr_get_overlayfs_options(const FstabEntry& entry) {
        }
        return ret;
    }
    return "";
}

bool AutoSetFsCreateCon::Set(const std::string& context) {
    if (setfscreatecon(context.c_str())) {
+1 −0
Original line number Diff line number Diff line
@@ -58,3 +58,4 @@ std::vector<const std::string> OverlayMountPoints();
bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
std::string GetEncodedBaseDirForMountPoint(const std::string& mount_point);