Skip to content

Commit

Permalink
Keep mirror shared before magic mount
Browse files Browse the repository at this point in the history
This allows mounting during post-fs-data be kept after magic mount
  • Loading branch information
yujincheng08 authored and topjohnwu committed Dec 22, 2023
1 parent 06687ab commit 27ece3c
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions native/src/core/bootstages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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<string, greater<>> mounted_dirs {{ get_magisk_tmp() }};
for (const auto &info: self_mount_info) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 27ece3c

Please sign in to comment.