From 1aade8f8a8ddf2cdd207e2e1bdd304d3e5f8a4d3 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Fri, 3 Mar 2023 22:53:53 +0800 Subject: [PATCH] No greedy match to find parent mount point This fixes /sys is considered as a parent mount point of /system --- native/src/core/bootstages.cpp | 17 ++++++++++------- native/src/zygisk/deny/revert.cpp | 7 ++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/native/src/core/bootstages.cpp b/native/src/core/bootstages.cpp index cf3041974..804a1aa75 100644 --- a/native/src/core/bootstages.cpp +++ b/native/src/core/bootstages.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -54,14 +54,17 @@ static void mount_mirrors() { if (auto mirror_dir = MAGISKTMP + "/" MIRRDIR; !mount_mirror("/", mirror_dir)) { LOGI("fallback to mount subtree\n"); // rootfs may fail, fallback to bind mount each mount point - std::vector mounted_dirs {{ MAGISKTMP }}; + set> mounted_dirs {{ MAGISKTMP }}; for (const auto &info: parse_mount_info("self")) { if (info.type == "rootfs"sv) continue; - bool mounted = std::any_of(mounted_dirs.begin(), mounted_dirs.end(), [&](const auto &dir) { - return str_starts(info.target, dir); - }); - if (!mounted && mount_mirror(info.target, mirror_dir + info.target)) { - mounted_dirs.emplace_back(info.target); + // the greatest mount point that less than info.target, which is possibly a parent + if (auto last_mount = mounted_dirs.upper_bound(info.target); + last_mount != mounted_dirs.end() && info.target.starts_with(*last_mount + '/')) { + continue; + } + if (mount_mirror(info.target, mirror_dir + info.target)) { + LOGD("%-8s: %s <- %s\n", "rbind", (mirror_dir + info.target).data(), info.target.data()); + mounted_dirs.insert(info.target); } } } diff --git a/native/src/zygisk/deny/revert.cpp b/native/src/zygisk/deny/revert.cpp index 47ccd7634..01cdcf01a 100644 --- a/native/src/zygisk/deny/revert.cpp +++ b/native/src/zygisk/deny/revert.cpp @@ -27,11 +27,12 @@ void revert_unmount() { if (targets.empty()) return; - for (auto last_target = targets.cbegin(), iter = next(targets.cbegin()); iter != targets.cend();) { - if (iter->starts_with(*last_target)) { + auto last_target = *targets.cbegin() + '/'; + for (auto iter = next(targets.cbegin()); iter != targets.cend();) { + if (iter->starts_with(last_target)) { iter = targets.erase(iter); } else { - last_target = iter++; + last_target = *iter++ + '/'; } }