Use rootfs for magisktmp if possible

This commit is contained in:
LoveSy
2025-11-14 23:32:00 +08:00
committed by John Wu
parent 283fc0f46f
commit bdbfb40383
6 changed files with 103 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
use crate::{LibcReturn, OsResult, Utf8CStr};
use crate::{Directory, LibcReturn, OsResult, ResultExt, Utf8CStr, Utf8CStrBufArr, WalkResult::{Continue, Skip}};
use nix::mount::{MntFlags, MsFlags, mount, umount2};
impl Utf8CStr {
@@ -81,4 +81,46 @@ impl Utf8CStr {
)
.check_os_err("set_mount_private", Some(self), None)
}
pub fn occupy(&self) {
Directory::open(self).and_then(|mut dir| {
dir.pre_order_walk(|entry| {
let mut path = Utf8CStrBufArr::default();
entry.resolve_path(&mut path)?;
let path = path.as_utf8_cstr();
mount(
Some(path),
path,
None::<&Utf8CStr>,
MsFlags::MS_BIND | MsFlags::MS_RDONLY,
None::<&Utf8CStr>,
).check_os_err("occupy", Some(path), None)?;
Ok(Continue)
}).log_ok();
Ok(())
}).log_ok();
}
pub fn unoccupy(&self) -> bool {
let mut ok = false;
Directory::open(self).and_then(|mut dir| {
ok = dir.pre_order_walk(|entry| {
let mut path = Utf8CStrBufArr::default();
entry.resolve_path(&mut path)?;
let path = path.as_utf8_cstr();
umount2(
path,
MntFlags::MNT_DETACH,
).check_os_err("unoccupy", Some(path), None)?;
if entry.is_dir() {
Ok(Skip)
} else {
Ok(Continue)
}
}).is_ok();
Ok(())
}).log_ok();
ok
}
}

View File

@@ -221,7 +221,8 @@ pub fn revert_unmount(pid: i32) {
// Unmount Magisk tmpfs and mounts from module files
for info in parse_mount_info("self") {
if info.source == "magisk" || info.root.starts_with("/adb/modules") {
if info.source == "magisk" || info.root.starts_with("/adb/modules") ||
(info.fs_type == "rootfs" && info.root.starts_with("/magisk")) {
targets.push(info.target);
}
}

View File

@@ -3,9 +3,10 @@ use crate::logging::setup_klog;
use crate::mount::is_rootfs;
use crate::twostage::hexpatch_init_for_second_stage;
use base::libc::{basename, getpid, mount, umask};
use base::{LibcReturn, LoggedResult, ResultExt, cstr, info, raw_cstr};
use base::{LibcReturn, LoggedResult, ResultExt, cstr, info, raw_cstr, nix, Utf8CStr};
use std::ffi::{CStr, c_char};
use std::ptr::null;
use base::nix::mount::MsFlags;
impl MagiskInit {
fn new(argv: *mut *mut c_char) -> Self {
@@ -31,7 +32,7 @@ impl MagiskInit {
fn first_stage(&self) {
info!("First Stage Init");
self.prepare_data();
let rootfs_magisktmp = self.prepare_data(true);
if !cstr!("/sdcard").exists() && !cstr!("/first_stage_ramdisk/sdcard").exists() {
self.hijack_init_with_switch_root();
@@ -41,11 +42,28 @@ impl MagiskInit {
// Fallback to hexpatch if /sdcard exists
hexpatch_init_for_second_stage(true);
}
if rootfs_magisktmp {
info!("Occupy /data.");
cstr!("/data").occupy();
}
}
fn second_stage(&mut self) {
info!("Second Stage Init");
if cstr!("/data").unoccupy() {
nix::mount::mount(
None::<&Utf8CStr>,
cstr!("/data"),
None::<&Utf8CStr>,
MsFlags::MS_REMOUNT,
Some(cstr!("size=100%")),
)
.check_os_err("mount", Some("/data"), Some("tmpfs"))
.log_ok();
}
cstr!("/init").unmount().ok();
cstr!("/system/bin/init").unmount().ok(); // just in case
cstr!("/data/init").remove().ok();
@@ -71,7 +89,7 @@ impl MagiskInit {
fn legacy_system_as_root(&mut self) {
info!("Legacy SAR Init");
self.prepare_data();
self.prepare_data(false);
let is_two_stage = self.mount_system_root();
if is_two_stage {
hexpatch_init_for_second_stage(false);
@@ -82,7 +100,7 @@ impl MagiskInit {
fn rootfs(&mut self) {
info!("RootFS Init");
self.prepare_data();
self.prepare_data(false);
self.restore_ramdisk_init();
self.patch_rw_root();
}

View File

@@ -73,22 +73,39 @@ pub(crate) fn is_rootfs() -> bool {
}
impl MagiskInit {
pub(crate) fn prepare_data(&self) {
pub(crate) fn prepare_data(&self, use_rootfs: bool) -> bool {
debug!("Setup data tmp");
cstr!("/data").mkdir(0o755).log_ok();
nix::mount::mount(
Some(cstr!("magisk")),
cstr!("/data"),
Some(cstr!("tmpfs")),
MsFlags::empty(),
Some(cstr!("mode=755")),
)
.check_os_err("mount", Some("/data"), Some("tmpfs"))
.log_ok();
cstr!("/init").copy_to(cstr!("/data/magiskinit")).ok();
cstr!("/.backup").copy_to(cstr!("/data/.backup")).ok();
cstr!("/overlay.d").copy_to(cstr!("/data/overlay.d")).ok();
let mut rootfs_magisktmp = false;
if use_rootfs {
cstr!("/magisk").mkdir(0o755).log_ok();
rootfs_magisktmp = cstr!("/magisk").bind_mount_to(cstr!("/data"), false)
.is_ok();
}
if rootfs_magisktmp {
cstr!("/init").rename_to(cstr!("/magisk/magiskinit")).log_ok();
cstr!("/.backup").copy_to(cstr!("/magisk/.backup")).ok();
cstr!("/overlay.d").rename_to(cstr!("/magisk/overlay.d")).ok();
} else {
nix::mount::mount(
Some(cstr!("magisk")),
cstr!("/data"),
Some(cstr!("tmpfs")),
MsFlags::empty(),
Some(cstr!("mode=755")),
)
.check_os_err("mount", Some("/data"), Some("tmpfs"))
.log_ok();
cstr!("/init").copy_to(cstr!("/data/magiskinit")).ok();
cstr!("/.backup").copy_to(cstr!("/data/.backup")).ok();
cstr!("/overlay.d").copy_to(cstr!("/data/overlay.d")).ok();
}
rootfs_magisktmp
}
pub(crate) fn exec_init(&mut self) {

View File

@@ -84,20 +84,12 @@ impl MagiskInit {
.log_ok();
debug!("Symlink /storage/self/primary -> /system/system/bin/init");
}
cstr!("/init").rename_to(cstr!("/sdcard")).log_ok();
// First try to mount magiskinit from rootfs to workaround Samsung RKP
if cstr!("/sdcard")
// Binding mounting from rootfs is not supported before Linux 3.12
cstr!("/sdcard").create(OFlag::O_RDONLY | OFlag::O_CLOEXEC, 0).log_ok();
cstr!("/data/magiskinit")
.bind_mount_to(cstr!("/sdcard"), false)
.is_ok()
{
debug!("Bind mount /sdcard -> /sdcard");
} else {
// Binding mounting from rootfs is not supported before Linux 3.12
cstr!("/data/magiskinit")
.bind_mount_to(cstr!("/sdcard"), false)
.log_ok();
debug!("Bind mount /data/magiskinit -> /sdcard");
}
.log_ok();
debug!("Bind mount /data/magiskinit -> /sdcard");
}
}

View File

@@ -110,7 +110,7 @@ impl SePolicy {
allow(["kernel"], ["rootfs", "tmpfs"], ["chr_file"], ["write"]);
// Allow magiskinit daemon to handle mock selinuxfs
allow(["kernel"], ["tmpfs"], ["fifo_file"], ["open", "read", "write"]);
allow(["kernel"], ["rootfs", "tmpfs"], ["fifo_file"], ["open", "read", "write"]);
// For relabelling files
allow(["rootfs"], ["labeledfs", "tmpfs"], ["filesystem"], ["associate"]);