diff --git a/native/src/core/bootstages.cpp b/native/src/core/bootstages.cpp index ff19049bb..20b99b6ab 100644 --- a/native/src/core/bootstages.cpp +++ b/native/src/core/bootstages.cpp @@ -20,13 +20,11 @@ bool zygisk_enabled = false; * Setup * *********/ -static bool mount_mirror(const std::string_view from, const std::string_view to) { +static bool rec_mount(const std::string_view from, const std::string_view to) { return !xmkdirs(to.data(), 0755) && // recursively bind mount to mirror dir, rootfs will fail before 3.12 kernel // because of MS_NOUSER - !mount(from.data(), to.data(), nullptr, MS_BIND | MS_REC, nullptr) && - // make mirror dir as a private mount so that it won't be affected by magic mount - !xmount(nullptr, to.data(), nullptr, MS_PRIVATE | MS_REC, nullptr); + !mount(from.data(), to.data(), nullptr, MS_BIND | MS_REC, nullptr); } static void mount_mirrors() { @@ -67,7 +65,7 @@ static void mount_mirrors() { if (!rw) continue; string preinit_dir = resolve_preinit_dir(info.target.data()); xmkdir(preinit_dir.data(), 0700); - if ((mounted = mount_mirror(preinit_dir, path))) { + if ((mounted = rec_mount(preinit_dir, path))) { xmount(nullptr, path, nullptr, MS_UNBINDABLE, nullptr); break; } @@ -83,10 +81,12 @@ static void mount_mirrors() { ssprintf(path, sizeof(path), "%s/" WORKERDIR, get_magisk_tmp()); xmount("worker", path, "tmpfs", 0, "mode=755"); xmount(nullptr, path, nullptr, MS_PRIVATE, nullptr); - // Recursively bind mount / to mirror dir - if (auto mirror_dir = get_magisk_tmp() + "/"s MIRRDIR; !mount_mirror("/", mirror_dir)) { + // Keep mirror shared so that mounting during post-fs-data will be propagated + if (auto mirror_dir = get_magisk_tmp() + "/"s MIRRDIR; !rec_mount("/", mirror_dir)) { LOGI("fallback to mount subtree\n"); + // create new a bind mount for easy make private + xmount(mirror_dir.data(), mirror_dir.data(), nullptr, MS_BIND, nullptr); // rootfs may fail, fallback to bind mount each mount point set> mounted_dirs {{ get_magisk_tmp() }}; for (const auto &info: self_mount_info) { @@ -96,7 +96,7 @@ static void mount_mirrors() { last_mount != mounted_dirs.end() && info.target.starts_with(*last_mount + '/')) { continue; } - if (mount_mirror(info.target, mirror_dir + info.target)) { + if (rec_mount(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); } @@ -342,6 +342,9 @@ bool MagiskD::post_fs_data() const { early_abort: auto mirror_dir = get_magisk_tmp() + "/"s MIRRDIR; + // make mirror dir as a private mount so that it won't be affected by magic mount + LOGD("make %s private\n", mirror_dir.data()); + xmount(nullptr, mirror_dir.data(), nullptr, MS_PRIVATE | MS_REC, nullptr); // We still do magic mount because root itself might need it load_modules(); // make mirror dir as a shared mount to make magisk --stop work for other ns