mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-27 15:20:58 +00:00
Enable mount for nix
This commit is contained in:
1
native/src/Cargo.lock
generated
1
native/src/Cargo.lock
generated
@@ -694,6 +694,7 @@ dependencies = [
|
||||
"cxx",
|
||||
"cxx-gen",
|
||||
"magiskpolicy",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -23,4 +23,4 @@ bytemuck = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
num-derive = { workspace = true }
|
||||
const_format = { workspace = true }
|
||||
nix = { workspace = true, features = ["fs"] }
|
||||
nix = { workspace = true, features = ["fs", "mount"] }
|
||||
|
||||
@@ -335,6 +335,11 @@ impl Utf8CStr {
|
||||
unsafe { CStr::from_bytes_with_nul_unchecked(&self.0) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_utf8_cstr(&self) -> &Utf8CStr {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_str(&self) -> &str {
|
||||
// SAFETY: Already UTF-8 validated during construction
|
||||
|
||||
@@ -1,91 +1,84 @@
|
||||
use crate::{LibcReturn, OsResult, Utf8CStr};
|
||||
use libc::c_ulong;
|
||||
use std::ptr;
|
||||
use nix::mount::{MntFlags, MsFlags, mount, umount2};
|
||||
|
||||
impl Utf8CStr {
|
||||
pub fn bind_mount_to<'a>(&'a self, path: &'a Utf8CStr, rec: bool) -> OsResult<'a, ()> {
|
||||
let flag = if rec { libc::MS_REC } else { 0 };
|
||||
unsafe {
|
||||
libc::mount(
|
||||
self.as_ptr(),
|
||||
path.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND | flag,
|
||||
ptr::null(),
|
||||
)
|
||||
.check_os_err("bind_mount", Some(self), Some(path))
|
||||
}
|
||||
let flag = if rec {
|
||||
MsFlags::MS_REC
|
||||
} else {
|
||||
MsFlags::empty()
|
||||
};
|
||||
mount(
|
||||
Some(self),
|
||||
path,
|
||||
None::<&Utf8CStr>,
|
||||
flag | MsFlags::MS_BIND,
|
||||
None::<&Utf8CStr>,
|
||||
)
|
||||
.check_os_err("bind_mount", Some(self), Some(path))
|
||||
}
|
||||
|
||||
pub fn remount_mount_point_flags(&self, flags: c_ulong) -> OsResult<'_, ()> {
|
||||
unsafe {
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
self.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_BIND | libc::MS_REMOUNT | flags,
|
||||
ptr::null(),
|
||||
)
|
||||
.check_os_err("remount", Some(self), None)
|
||||
}
|
||||
pub fn remount_mount_point_flags(&self, flags: MsFlags) -> OsResult<'_, ()> {
|
||||
mount(
|
||||
None::<&Utf8CStr>,
|
||||
self,
|
||||
None::<&Utf8CStr>,
|
||||
MsFlags::MS_BIND | MsFlags::MS_REMOUNT | flags,
|
||||
None::<&Utf8CStr>,
|
||||
)
|
||||
.check_os_err("remount", Some(self), None)
|
||||
}
|
||||
|
||||
pub fn remount_mount_flags(&self, flags: c_ulong) -> OsResult<'_, ()> {
|
||||
unsafe {
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
self.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_REMOUNT | flags,
|
||||
ptr::null(),
|
||||
)
|
||||
.check_os_err("remount", Some(self), None)
|
||||
}
|
||||
pub fn remount_mount_flags(&self, flags: MsFlags) -> OsResult<'_, ()> {
|
||||
mount(
|
||||
None::<&Utf8CStr>,
|
||||
self,
|
||||
None::<&Utf8CStr>,
|
||||
MsFlags::MS_REMOUNT | flags,
|
||||
None::<&Utf8CStr>,
|
||||
)
|
||||
.check_os_err("remount", Some(self), None)
|
||||
}
|
||||
|
||||
pub fn remount_with_data(&self, data: &Utf8CStr) -> OsResult<'_, ()> {
|
||||
unsafe {
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
self.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_REMOUNT,
|
||||
data.as_ptr().cast(),
|
||||
)
|
||||
.check_os_err("remount", Some(self), None)
|
||||
}
|
||||
mount(
|
||||
None::<&Utf8CStr>,
|
||||
self,
|
||||
None::<&Utf8CStr>,
|
||||
MsFlags::MS_REMOUNT,
|
||||
Some(data),
|
||||
)
|
||||
.check_os_err("remount", Some(self), None)
|
||||
}
|
||||
|
||||
pub fn move_mount_to<'a>(&'a self, path: &'a Utf8CStr) -> OsResult<'a, ()> {
|
||||
unsafe {
|
||||
libc::mount(
|
||||
self.as_ptr(),
|
||||
path.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_MOVE,
|
||||
ptr::null(),
|
||||
)
|
||||
.check_os_err("move_mount", Some(self), Some(path))
|
||||
}
|
||||
mount(
|
||||
Some(self),
|
||||
path,
|
||||
None::<&Utf8CStr>,
|
||||
MsFlags::MS_MOVE,
|
||||
None::<&Utf8CStr>,
|
||||
)
|
||||
.check_os_err("move_mount", Some(self), Some(path))
|
||||
}
|
||||
|
||||
pub fn unmount(&self) -> OsResult<'_, ()> {
|
||||
unsafe {
|
||||
libc::umount2(self.as_ptr(), libc::MNT_DETACH).check_os_err("unmount", Some(self), None)
|
||||
}
|
||||
umount2(self, MntFlags::MNT_DETACH).check_os_err("unmount", Some(self), None)
|
||||
}
|
||||
|
||||
pub fn set_mount_private(&self, recursive: bool) -> OsResult<'_, ()> {
|
||||
let flag = if recursive { libc::MS_REC } else { 0 };
|
||||
unsafe {
|
||||
libc::mount(
|
||||
ptr::null(),
|
||||
self.as_ptr(),
|
||||
ptr::null(),
|
||||
libc::MS_PRIVATE | flag,
|
||||
ptr::null(),
|
||||
)
|
||||
.check_os_err("set_mount_private", Some(self), None)
|
||||
}
|
||||
pub fn set_mount_private(&self, rec: bool) -> OsResult<'_, ()> {
|
||||
let flag = if rec {
|
||||
MsFlags::MS_REC
|
||||
} else {
|
||||
MsFlags::empty()
|
||||
};
|
||||
mount(
|
||||
None::<&Utf8CStr>,
|
||||
self,
|
||||
None::<&Utf8CStr>,
|
||||
flag | MsFlags::MS_PRIVATE,
|
||||
None::<&Utf8CStr>,
|
||||
)
|
||||
.check_os_err("set_mount_private", Some(self), None)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,4 @@ bytemuck = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
bit-set = { workspace = true }
|
||||
argh = { workspace = true }
|
||||
nix = { workspace = true, features = ["fs", "poll", "signal", "term", "zerocopy"] }
|
||||
nix = { workspace = true, features = ["fs", "mount", "poll", "signal", "term", "zerocopy"] }
|
||||
|
||||
@@ -23,6 +23,7 @@ use base::{
|
||||
cstr, error, info, libc,
|
||||
};
|
||||
use nix::fcntl::OFlag;
|
||||
use nix::mount::MsFlags;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Write};
|
||||
@@ -384,7 +385,7 @@ pub fn daemon_entry() {
|
||||
|
||||
// Remount rootfs as read-only if requested
|
||||
if std::env::var_os("REMOUNT_ROOT").is_some() {
|
||||
cstr!("/").remount_mount_flags(libc::MS_RDONLY).log_ok();
|
||||
cstr!("/").remount_mount_flags(MsFlags::MS_RDONLY).log_ok();
|
||||
unsafe { std::env::remove_var("REMOUNT_ROOT") };
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ use base::{
|
||||
Utf8CStrBuf, Utf8CString, WalkResult, clone_attr, cstr, debug, error, info, libc, raw_cstr,
|
||||
warn,
|
||||
};
|
||||
use libc::MS_RDONLY;
|
||||
use nix::{fcntl::OFlag, unistd::UnlinkatFlags};
|
||||
use nix::{fcntl::OFlag, mount::MsFlags, unistd::UnlinkatFlags};
|
||||
use std::collections::BTreeMap;
|
||||
use std::os::fd::IntoRawFd;
|
||||
use std::path::{Component, Path};
|
||||
@@ -40,7 +39,7 @@ fn bind_mount(reason: &str, src: &Utf8CStr, dest: &Utf8CStr, rec: bool) {
|
||||
// Ignore any kind of error here. If a single bind mount fails due to selinux permissions or
|
||||
// kernel limitations, don't let it break module mount entirely.
|
||||
src.bind_mount_to(dest, rec).log_ok();
|
||||
dest.remount_mount_point_flags(MS_RDONLY).log_ok();
|
||||
dest.remount_mount_point_flags(MsFlags::MS_RDONLY).log_ok();
|
||||
}
|
||||
|
||||
fn mount_dummy<'a>(
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
use std::{
|
||||
cmp::Ordering::{Greater, Less},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use num_traits::AsPrimitive;
|
||||
|
||||
use base::libc::{c_uint, dev_t};
|
||||
use crate::consts::{MODULEMNT, MODULEROOT, PREINITDEV, PREINITMIRR, WORKERDIR};
|
||||
use crate::ffi::{get_magisk_tmp, resolve_preinit_dir, switch_mnt_ns};
|
||||
use crate::resetprop::get_prop;
|
||||
use base::{
|
||||
FsPathBuilder, LibcReturn, LoggedResult, MountInfo, ResultExt, Utf8CStr, Utf8CStrBuf, cstr,
|
||||
debug, info, libc, parse_mount_info, warn,
|
||||
};
|
||||
|
||||
use crate::consts::{MODULEMNT, MODULEROOT, PREINITDEV, PREINITMIRR, WORKERDIR};
|
||||
use crate::ffi::{get_magisk_tmp, resolve_preinit_dir, switch_mnt_ns};
|
||||
use crate::resetprop::get_prop;
|
||||
use libc::{c_uint, dev_t};
|
||||
use nix::{
|
||||
mount::MsFlags,
|
||||
sys::stat::{Mode, SFlag, mknod},
|
||||
};
|
||||
use num_traits::AsPrimitive;
|
||||
use std::{cmp::Ordering::Greater, cmp::Ordering::Less, path::Path, path::PathBuf};
|
||||
|
||||
pub fn setup_preinit_dir() {
|
||||
let magisk_tmp = get_magisk_tmp();
|
||||
@@ -69,7 +67,7 @@ pub fn setup_module_mount() {
|
||||
let _: LoggedResult<()> = try {
|
||||
module_mnt.mkdir(0o755)?;
|
||||
cstr!(MODULEROOT).bind_mount_to(&module_mnt, false)?;
|
||||
module_mnt.remount_mount_point_flags(libc::MS_RDONLY)?;
|
||||
module_mnt.remount_mount_point_flags(MsFlags::MS_RDONLY)?;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -194,15 +192,14 @@ pub fn find_preinit_device() -> String {
|
||||
if std::env::var_os("MAKEDEV").is_some() {
|
||||
buf.clear();
|
||||
let dev_path = buf.append_path(&tmp).append_path(PREINITDEV);
|
||||
unsafe {
|
||||
libc::mknod(
|
||||
dev_path.as_ptr(),
|
||||
libc::S_IFBLK | 0o600,
|
||||
info.device as dev_t,
|
||||
)
|
||||
.check_os_err("mknod", Some(dev_path), None)
|
||||
.log_ok();
|
||||
}
|
||||
mknod(
|
||||
dev_path.as_utf8_cstr(),
|
||||
SFlag::S_IFBLK,
|
||||
Mode::from_bits_truncate(0o600),
|
||||
info.device as dev_t,
|
||||
)
|
||||
.check_os_err("mknod", Some(dev_path), None)
|
||||
.log_ok();
|
||||
}
|
||||
}
|
||||
Path::new(&info.source)
|
||||
@@ -248,10 +245,8 @@ pub fn revert_unmount(pid: i32) {
|
||||
|
||||
for mut target in targets {
|
||||
let target = Utf8CStr::from_string(&mut target);
|
||||
unsafe {
|
||||
if libc::umount2(target.as_ptr(), libc::MNT_DETACH) == 0 {
|
||||
debug!("denylist: Unmounted ({})", target);
|
||||
}
|
||||
if target.unmount().is_ok() {
|
||||
debug!("denylist: Unmounted ({})", target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
native/src/external/crt0
vendored
2
native/src/external/crt0
vendored
Submodule native/src/external/crt0 updated: f7f5d092b2...9dfa67b4d5
@@ -14,3 +14,4 @@ cxx-gen = { workspace = true }
|
||||
base = { path = "../base" }
|
||||
magiskpolicy = { path = "../sepolicy", default-features = false }
|
||||
cxx = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
use crate::ffi::MagiskInit;
|
||||
use base::libc::{TMPFS_MAGIC, statfs};
|
||||
use base::{
|
||||
Directory, FsPathBuilder, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, debug, libc,
|
||||
libc::{chdir, chroot, execve, exit, mount},
|
||||
parse_mount_info, raw_cstr,
|
||||
nix, parse_mount_info, raw_cstr,
|
||||
};
|
||||
use cxx::CxxString;
|
||||
use std::ffi::c_long;
|
||||
use nix::{
|
||||
mount::MsFlags,
|
||||
sys::statfs::{FsType, TMPFS_MAGIC, statfs},
|
||||
unistd::{chdir, chroot},
|
||||
};
|
||||
use num_traits::AsPrimitive;
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
ops::Bound::{Excluded, Unbounded},
|
||||
@@ -43,11 +46,9 @@ pub(crate) fn switch_root(path: &Utf8CStr) {
|
||||
target.move_mount_to(&new_path)?;
|
||||
mounts.insert(info.target);
|
||||
}
|
||||
unsafe {
|
||||
chdir(path.as_ptr()).check_err()?;
|
||||
path.move_mount_to(cstr!("/"))?;
|
||||
chroot(raw_cstr!("."));
|
||||
}
|
||||
chdir(path)?;
|
||||
path.move_mount_to(cstr!("/"))?;
|
||||
chroot(cstr!("."))?;
|
||||
|
||||
debug!("Cleaning rootfs");
|
||||
rootfs.remove_all()?;
|
||||
@@ -65,13 +66,13 @@ pub(crate) fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
const RAMFS_MAGIC: u64 = 0x858458f6;
|
||||
const RAMFS_MAGIC: u32 = 0x858458f6;
|
||||
|
||||
pub(crate) fn is_rootfs() -> bool {
|
||||
unsafe {
|
||||
let mut sfs: statfs = std::mem::zeroed();
|
||||
statfs(raw_cstr!("/"), &mut sfs);
|
||||
sfs.f_type as u64 == RAMFS_MAGIC || sfs.f_type as c_long == TMPFS_MAGIC
|
||||
if let Ok(s) = statfs(cstr!("/")) {
|
||||
s.filesystem_type() == FsType(RAMFS_MAGIC.as_()) || s.filesystem_type() == TMPFS_MAGIC
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,23 +80,19 @@ impl MagiskInit {
|
||||
pub(crate) fn prepare_data(&self) {
|
||||
debug!("Setup data tmp");
|
||||
cstr!("/data").mkdir(0o755).log_ok();
|
||||
unsafe {
|
||||
mount(
|
||||
raw_cstr!("magisk"),
|
||||
raw_cstr!("/data"),
|
||||
raw_cstr!("tmpfs"),
|
||||
0,
|
||||
raw_cstr!("mode=755").cast(),
|
||||
)
|
||||
}
|
||||
.check_err()
|
||||
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")).log_ok();
|
||||
cstr!("/.backup").copy_to(cstr!("/data/.backup")).log_ok();
|
||||
cstr!("/overlay.d")
|
||||
.copy_to(cstr!("/data/overlay.d"))
|
||||
.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();
|
||||
}
|
||||
|
||||
pub(crate) fn exec_init(&mut self) {
|
||||
@@ -106,10 +103,10 @@ impl MagiskInit {
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
execve(raw_cstr!("/init"), self.argv.cast(), environ.cast())
|
||||
libc::execve(raw_cstr!("/init"), self.argv.cast(), environ.cast())
|
||||
.check_err()
|
||||
.log_ok();
|
||||
exit(1);
|
||||
}
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user