You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Make FsPath a trait
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::ffi::{BootConfig, MagiskInit, backup_init};
|
||||
use base::{BytesExt, MappedFile, path};
|
||||
use base::{BytesExt, FsPath, MappedFile, cstr};
|
||||
|
||||
impl BootConfig {
|
||||
#[allow(unused_imports, unused_unsafe)]
|
||||
@@ -37,11 +37,11 @@ impl BootConfig {
|
||||
|
||||
impl MagiskInit {
|
||||
pub(crate) fn check_two_stage(&self) -> bool {
|
||||
path!("/first_stage_ramdisk").exists() ||
|
||||
path!("/second_stage_resources").exists() ||
|
||||
path!("/system/bin/init").exists() ||
|
||||
cstr!("/first_stage_ramdisk").exists() ||
|
||||
cstr!("/second_stage_resources").exists() ||
|
||||
cstr!("/system/bin/init").exists() ||
|
||||
// Use the apex folder to determine whether 2SI (Android 10+)
|
||||
path!("/apex").exists() ||
|
||||
cstr!("/apex").exists() ||
|
||||
// If we still have no indication, parse the original init and see what's up
|
||||
MappedFile::open(backup_init())
|
||||
.map(|data| data.contains(b"selinux_setup"))
|
||||
|
||||
+19
-19
@@ -6,9 +6,9 @@ use crate::{
|
||||
logging::setup_klog,
|
||||
};
|
||||
use base::{
|
||||
FsPath, LibcReturn, LoggedResult, ResultExt, info,
|
||||
FsPath, FsPathMnt, LibcReturn, LoggedResult, ResultExt, cstr, info,
|
||||
libc::{basename, getpid, mount, umask},
|
||||
path, raw_cstr,
|
||||
raw_cstr,
|
||||
};
|
||||
use std::{
|
||||
ffi::{CStr, c_char},
|
||||
@@ -41,7 +41,7 @@ impl MagiskInit {
|
||||
info!("First Stage Init");
|
||||
self.prepare_data();
|
||||
|
||||
if !path!("/sdcard").exists() && !path!("/first_stage_ramdisk/sdcard").exists() {
|
||||
if !cstr!("/sdcard").exists() && !cstr!("/first_stage_ramdisk/sdcard").exists() {
|
||||
self.hijack_init_with_switch_root();
|
||||
self.restore_ramdisk_init();
|
||||
} else {
|
||||
@@ -54,9 +54,9 @@ impl MagiskInit {
|
||||
fn second_stage(&mut self) {
|
||||
info!("Second Stage Init");
|
||||
|
||||
path!("/init").unmount().ok();
|
||||
path!("/system/bin/init").unmount().ok(); // just in case
|
||||
path!("/data/init").remove().ok();
|
||||
cstr!("/init").unmount().ok();
|
||||
cstr!("/system/bin/init").unmount().ok(); // just in case
|
||||
cstr!("/data/init").remove().ok();
|
||||
|
||||
unsafe {
|
||||
// Make sure init dmesg logs won't get messed up
|
||||
@@ -66,10 +66,10 @@ impl MagiskInit {
|
||||
// Some weird devices like meizu, uses 2SI but still have legacy rootfs
|
||||
if is_rootfs() {
|
||||
// We are still on rootfs, so make sure we will execute the init of the 2nd stage
|
||||
let init_path = path!("/init");
|
||||
let init_path = cstr!("/init");
|
||||
init_path.remove().ok();
|
||||
init_path
|
||||
.create_symlink_to(path!("/system/bin/init"))
|
||||
.create_symlink_to(cstr!("/system/bin/init"))
|
||||
.log_ok();
|
||||
self.patch_rw_root();
|
||||
} else {
|
||||
@@ -98,29 +98,29 @@ impl MagiskInit {
|
||||
fn recovery(&self) {
|
||||
info!("Ramdisk is recovery, abort");
|
||||
self.restore_ramdisk_init();
|
||||
path!("/.backup").remove_all().ok();
|
||||
cstr!("/.backup").remove_all().ok();
|
||||
}
|
||||
|
||||
fn restore_ramdisk_init(&self) {
|
||||
path!("/init").remove().ok();
|
||||
cstr!("/init").remove().ok();
|
||||
|
||||
let orig_init = FsPath::from(backup_init());
|
||||
let orig_init = backup_init();
|
||||
|
||||
if orig_init.exists() {
|
||||
orig_init.rename_to(path!("/init")).log_ok();
|
||||
orig_init.rename_to(cstr!("/init")).log_ok();
|
||||
} else {
|
||||
// If the backup init is missing, this means that the boot ramdisk
|
||||
// was created from scratch, and the real init is in a separate CPIO,
|
||||
// which is guaranteed to be placed at /system/bin/init.
|
||||
path!("/init")
|
||||
.create_symlink_to(path!("/system/bin/init"))
|
||||
cstr!("/init")
|
||||
.create_symlink_to(cstr!("/system/bin/init"))
|
||||
.log_ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn start(&mut self) -> LoggedResult<()> {
|
||||
if !path!("/proc/cmdline").exists() {
|
||||
path!("/proc").mkdir(0o755)?;
|
||||
if !cstr!("/proc/cmdline").exists() {
|
||||
cstr!("/proc").mkdir(0o755)?;
|
||||
unsafe {
|
||||
mount(
|
||||
raw_cstr!("proc"),
|
||||
@@ -133,8 +133,8 @@ impl MagiskInit {
|
||||
.check_io_err()?;
|
||||
self.mount_list.push("/proc".to_string());
|
||||
}
|
||||
if !path!("/sys/block").exists() {
|
||||
path!("/sys").mkdir(0o755)?;
|
||||
if !cstr!("/sys/block").exists() {
|
||||
cstr!("/sys").mkdir(0o755)?;
|
||||
unsafe {
|
||||
mount(
|
||||
raw_cstr!("sysfs"),
|
||||
@@ -159,7 +159,7 @@ impl MagiskInit {
|
||||
self.legacy_system_as_root();
|
||||
} else if self.config.force_normal_boot {
|
||||
self.first_stage();
|
||||
} else if path!("/sbin/recovery").exists() || path!("/system/bin/recovery").exists() {
|
||||
} else if cstr!("/sbin/recovery").exists() || cstr!("/system/bin/recovery").exists() {
|
||||
self.recovery();
|
||||
} else if self.check_two_stage() {
|
||||
self.first_stage();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#![feature(try_blocks)]
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use base::FsPath;
|
||||
use logging::setup_klog;
|
||||
// Has to be pub so all symbols in that crate is included
|
||||
pub use magiskpolicy;
|
||||
@@ -106,18 +105,3 @@ pub mod ffi {
|
||||
unsafe fn patch_fissiond(self: &mut MagiskInit, tmp_path: *const c_char);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn preload_lib() -> &'static FsPath {
|
||||
FsPath::from(ffi::preload_lib())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn preload_policy() -> &'static FsPath {
|
||||
FsPath::from(ffi::preload_policy())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn preload_ack() -> &'static FsPath {
|
||||
FsPath::from(ffi::preload_ack())
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use base::{
|
||||
LOGGER, LogLevel, Logger, Utf8CStr, cstr,
|
||||
FsPath, LOGGER, LogLevel, Logger, Utf8CStr, cstr,
|
||||
libc::{
|
||||
O_CLOEXEC, O_RDWR, O_WRONLY, S_IFCHR, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, SYS_dup3,
|
||||
makedev, mknod, syscall,
|
||||
},
|
||||
open_fd, path, raw_cstr,
|
||||
open_fd, raw_cstr,
|
||||
};
|
||||
use std::{
|
||||
fs::File,
|
||||
@@ -23,7 +23,7 @@ pub fn setup_klog() {
|
||||
if fd.is_err() {
|
||||
mknod(raw_cstr!("/null"), S_IFCHR | 0o666, makedev(1, 3));
|
||||
fd = open_fd!(cstr!("/null"), O_RDWR | O_CLOEXEC);
|
||||
path!("/null").remove().ok();
|
||||
cstr!("/null").remove().ok();
|
||||
}
|
||||
if let Ok(ref fd) = fd {
|
||||
syscall(SYS_dup3, fd, STDIN_FILENO, O_CLOEXEC);
|
||||
@@ -36,7 +36,7 @@ pub fn setup_klog() {
|
||||
if fd.is_err() {
|
||||
mknod(raw_cstr!("/kmsg"), S_IFCHR | 0o666, makedev(1, 11));
|
||||
fd = open_fd!(cstr!("/kmsg"), O_WRONLY | O_CLOEXEC);
|
||||
path!("/kmsg").remove().ok();
|
||||
cstr!("/kmsg").remove().ok();
|
||||
}
|
||||
KMSG = fd.map(|fd| fd.into_raw_fd()).unwrap_or(-1);
|
||||
}
|
||||
|
||||
+11
-10
@@ -1,9 +1,10 @@
|
||||
use crate::ffi::MagiskInit;
|
||||
use base::libc::{TMPFS_MAGIC, statfs};
|
||||
use base::{
|
||||
Directory, FsPath, FsPathBuf, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, debug, libc,
|
||||
Directory, FsPath, FsPathBuf, FsPathMnt, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr,
|
||||
debug, libc,
|
||||
libc::{chdir, chroot, execve, exit, mount},
|
||||
parse_mount_info, path, raw_cstr,
|
||||
parse_mount_info, raw_cstr,
|
||||
};
|
||||
use cxx::CxxString;
|
||||
use std::ffi::c_long;
|
||||
@@ -36,7 +37,7 @@ pub(crate) fn switch_root(path: &Utf8CStr) {
|
||||
}
|
||||
|
||||
let mut target = info.target.clone();
|
||||
let target = FsPath::from(Utf8CStr::from_string(&mut target));
|
||||
let target = Utf8CStr::from_string(&mut target);
|
||||
let new_path = FsPathBuf::default()
|
||||
.join(path)
|
||||
.join(info.target.trim_start_matches('/'));
|
||||
@@ -46,7 +47,7 @@ pub(crate) fn switch_root(path: &Utf8CStr) {
|
||||
}
|
||||
unsafe {
|
||||
chdir(path.as_ptr()).check_io_err()?;
|
||||
FsPath::from(path).move_mount_to(path!("/"))?;
|
||||
path.move_mount_to(cstr!("/"))?;
|
||||
chroot(raw_cstr!("."));
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ pub(crate) fn is_rootfs() -> bool {
|
||||
impl MagiskInit {
|
||||
pub(crate) fn prepare_data(&self) {
|
||||
debug!("Setup data tmp");
|
||||
path!("/data").mkdir(0o755).log_ok();
|
||||
cstr!("/data").mkdir(0o755).log_ok();
|
||||
unsafe {
|
||||
mount(
|
||||
raw_cstr!("magisk"),
|
||||
@@ -92,16 +93,16 @@ impl MagiskInit {
|
||||
.check_io_err()
|
||||
.log_ok();
|
||||
|
||||
path!("/init").copy_to(path!("/data/magiskinit")).log_ok();
|
||||
path!("/.backup").copy_to(path!("/data/.backup")).log_ok();
|
||||
path!("/overlay.d")
|
||||
.copy_to(path!("/data/overlay.d"))
|
||||
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();
|
||||
}
|
||||
|
||||
pub(crate) fn exec_init(&mut self) {
|
||||
for path in self.mount_list.iter_mut().rev() {
|
||||
let path = FsPath::from(Utf8CStr::from_string(path));
|
||||
let path = Utf8CStr::from_string(path);
|
||||
if path.unmount().log().is_ok() {
|
||||
debug!("Unmount [{}]", path);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::consts::{ROOTMNT, ROOTOVL};
|
||||
use crate::ffi::MagiskInit;
|
||||
use base::libc::{O_CREAT, O_RDONLY, O_WRONLY};
|
||||
use base::{
|
||||
BufReadExt, Directory, FsPath, FsPathBuf, LoggedResult, ResultExt, Utf8CStr, Utf8CString,
|
||||
clone_attr, cstr, cstr_buf, debug, path,
|
||||
BufReadExt, Directory, FsPath, FsPathBuf, FsPathMnt, LoggedResult, ResultExt, Utf8CStr,
|
||||
Utf8CString, clone_attr, cstr, cstr_buf, debug,
|
||||
};
|
||||
use std::io::BufReader;
|
||||
use std::{
|
||||
@@ -47,7 +47,7 @@ pub struct OverlayAttr(Utf8CString, Utf8CString);
|
||||
|
||||
impl MagiskInit {
|
||||
pub(crate) fn parse_config_file(&mut self) {
|
||||
if let Ok(fd) = path!("/data/.backup/.magisk").open(O_RDONLY) {
|
||||
if let Ok(fd) = cstr!("/data/.backup/.magisk").open(O_RDONLY) {
|
||||
let mut reader = BufReader::new(fd);
|
||||
reader.foreach_props(|key, val| {
|
||||
if key == "PREINITDEVICE" {
|
||||
@@ -102,7 +102,7 @@ impl MagiskInit {
|
||||
let mut mount_list = String::new();
|
||||
self.mount_impl(cstr!(ROOTOVL), dest, &mut mount_list)
|
||||
.log_ok();
|
||||
if let Ok(mut fd) = path!(ROOTMNT).create(O_CREAT | O_WRONLY, 0) {
|
||||
if let Ok(mut fd) = cstr!(ROOTMNT).create(O_CREAT | O_WRONLY, 0) {
|
||||
fd.write(mount_list.as_bytes()).log_ok();
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ impl MagiskInit {
|
||||
pub(crate) fn restore_overlay_contexts(&self) {
|
||||
self.overlay_con.iter().for_each(|attr| {
|
||||
let OverlayAttr(path, con) = attr;
|
||||
FsPath::from(path).set_secontext(con).log_ok();
|
||||
path.set_secontext(con).log_ok();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+20
-21
@@ -1,10 +1,9 @@
|
||||
use crate::consts::{PREINITMIRR, SELINUXMOCK};
|
||||
use crate::ffi::{MagiskInit, split_plat_cil};
|
||||
use crate::{preload_ack, preload_lib, preload_policy};
|
||||
use crate::ffi::{MagiskInit, preload_ack, preload_lib, preload_policy, split_plat_cil};
|
||||
use base::const_format::concatcp;
|
||||
use base::{
|
||||
BytesExt, FsPath, LibcReturn, LoggedResult, MappedFile, ResultExt, cstr, debug, error, info,
|
||||
libc, path, raw_cstr,
|
||||
BytesExt, FsPath, FsPathMnt, LibcReturn, LoggedResult, MappedFile, ResultExt, Utf8CStr, cstr,
|
||||
debug, error, info, libc, raw_cstr,
|
||||
};
|
||||
use magiskpolicy::ffi::SePolicy;
|
||||
use std::io::{Read, Write};
|
||||
@@ -12,17 +11,17 @@ use std::ptr;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
const POLICY_VERSION: &FsPath = path!("/selinux_version");
|
||||
const POLICY_VERSION: &Utf8CStr = cstr!("/selinux_version");
|
||||
|
||||
const MOCK_VERSION: &FsPath = path!(concatcp!(SELINUXMOCK, "/version"));
|
||||
const MOCK_LOAD: &FsPath = path!(concatcp!(SELINUXMOCK, "/load"));
|
||||
const MOCK_ENFORCE: &FsPath = path!(concatcp!(SELINUXMOCK, "/enforce"));
|
||||
const MOCK_REQPROT: &FsPath = path!(concatcp!(SELINUXMOCK, "/checkreqprot"));
|
||||
const MOCK_VERSION: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/version"));
|
||||
const MOCK_LOAD: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/load"));
|
||||
const MOCK_ENFORCE: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/enforce"));
|
||||
const MOCK_REQPROT: &Utf8CStr = cstr!(concatcp!(SELINUXMOCK, "/checkreqprot"));
|
||||
|
||||
const SELINUX_MNT: &str = "/sys/fs/selinux";
|
||||
const SELINUX_ENFORCE: &FsPath = path!(concatcp!(SELINUX_MNT, "/enforce"));
|
||||
const SELINUX_LOAD: &FsPath = path!(concatcp!(SELINUX_MNT, "/load"));
|
||||
const SELINUX_REQPROT: &FsPath = path!(concatcp!(SELINUX_MNT, "/checkreqprot"));
|
||||
const SELINUX_ENFORCE: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/enforce"));
|
||||
const SELINUX_LOAD: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/load"));
|
||||
const SELINUX_REQPROT: &Utf8CStr = cstr!(concatcp!(SELINUX_MNT, "/checkreqprot"));
|
||||
|
||||
enum SePatchStrategy {
|
||||
// 2SI, Android 10+
|
||||
@@ -49,13 +48,13 @@ enum SePatchStrategy {
|
||||
// node, and because both has been replaced with FIFO files, init will block until we
|
||||
// handle it, effectively hijacking its control flow until the patched sepolicy is loaded.
|
||||
|
||||
fn mock_fifo(target: &FsPath, mock: &FsPath) -> LoggedResult<()> {
|
||||
fn mock_fifo(target: &Utf8CStr, mock: &Utf8CStr) -> LoggedResult<()> {
|
||||
debug!("Hijack [{}]", target);
|
||||
mock.mkfifo(0o666)?;
|
||||
mock.bind_mount_to(target).log()
|
||||
}
|
||||
|
||||
fn mock_file(target: &FsPath, mock: &FsPath) -> LoggedResult<()> {
|
||||
fn mock_file(target: &Utf8CStr, mock: &Utf8CStr) -> LoggedResult<()> {
|
||||
debug!("Hijack [{}]", target);
|
||||
drop(mock.create(libc::O_RDONLY, 0o666)?);
|
||||
mock.bind_mount_to(target).log()
|
||||
@@ -68,7 +67,7 @@ impl MagiskInit {
|
||||
|
||||
fn cleanup_and_load(&self, rules: &str) {
|
||||
// Cleanup the hijacks
|
||||
path!("/init").unmount().ok();
|
||||
cstr!("/init").unmount().ok();
|
||||
SELINUX_LOAD.unmount().log_ok();
|
||||
SELINUX_ENFORCE.unmount().ok();
|
||||
SELINUX_REQPROT.unmount().ok();
|
||||
@@ -79,7 +78,7 @@ impl MagiskInit {
|
||||
sepol.to_file(SELINUX_LOAD);
|
||||
|
||||
// For some reason, restorecon on /init won't work in some cases
|
||||
path!("/init")
|
||||
cstr!("/init")
|
||||
.follow_link()
|
||||
.set_secontext(cstr!("u:object_r:init_exec:s0"))
|
||||
.ok();
|
||||
@@ -89,10 +88,10 @@ impl MagiskInit {
|
||||
}
|
||||
|
||||
fn handle_sepolicy_impl(&mut self) -> LoggedResult<()> {
|
||||
path!(SELINUXMOCK).mkdir(0o711)?;
|
||||
cstr!(SELINUXMOCK).mkdir(0o711)?;
|
||||
|
||||
let mut rules = String::new();
|
||||
let rule_file = path!(concatcp!("/data/", PREINITMIRR, "/sepolicy.rule"));
|
||||
let rule_file = cstr!(concatcp!("/data/", PREINITMIRR, "/sepolicy.rule"));
|
||||
if rule_file.exists() {
|
||||
debug!("Loading custom sepolicy patch: [{}]", rule_file);
|
||||
rule_file.open(libc::O_RDONLY)?.read_to_string(&mut rules)?;
|
||||
@@ -102,7 +101,7 @@ impl MagiskInit {
|
||||
|
||||
let strat: SePatchStrategy;
|
||||
|
||||
if path!("/system/bin/init").exists() {
|
||||
if cstr!("/system/bin/init").exists() {
|
||||
strat = SePatchStrategy::LdPreload;
|
||||
} else {
|
||||
let init = MappedFile::open(cstr!("/init"))?;
|
||||
@@ -124,7 +123,7 @@ impl MagiskInit {
|
||||
SePatchStrategy::LdPreload => {
|
||||
info!("SePatchStrategy: LD_PRELOAD");
|
||||
|
||||
path!("init-ld").copy_to(preload_lib())?;
|
||||
cstr!("init-ld").copy_to(preload_lib())?;
|
||||
unsafe {
|
||||
libc::setenv(raw_cstr!("LD_PRELOAD"), preload_lib().as_ptr(), 1);
|
||||
}
|
||||
@@ -137,7 +136,7 @@ impl MagiskInit {
|
||||
// selinuxfs was not already mounted, mount it ourselves
|
||||
|
||||
// Remount procfs with proper options
|
||||
path!("/proc").remount_with_data(cstr!("hidepid=2,gid=3009"))?;
|
||||
cstr!("/proc").remount_with_data(cstr!("hidepid=2,gid=3009"))?;
|
||||
|
||||
// Preserve sysfs and procfs
|
||||
self.mount_list.retain(|s| s != "/proc" && s != "/sys");
|
||||
|
||||
+14
-15
@@ -1,8 +1,7 @@
|
||||
use crate::ffi::MagiskInit;
|
||||
use base::{
|
||||
LoggedResult, MappedFile, MutBytesExt, ResultExt, cstr, debug, error,
|
||||
FsPath, FsPathMnt, LoggedResult, MappedFile, MutBytesExt, ResultExt, cstr, debug, error,
|
||||
libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_WRONLY},
|
||||
path,
|
||||
};
|
||||
use std::io::Write;
|
||||
|
||||
@@ -29,8 +28,8 @@ pub(crate) fn hexpatch_init_for_second_stage(writable: bool) {
|
||||
|
||||
if !writable {
|
||||
// If we cannot directly modify /init, we need to bind mount a replacement on top of it
|
||||
let src = path!("/init");
|
||||
let dest = path!("/data/init");
|
||||
let src = cstr!("/init");
|
||||
let dest = cstr!("/data/init");
|
||||
let _: LoggedResult<()> = try {
|
||||
{
|
||||
let mut fd = dest.create(O_CREAT | O_WRONLY, 0)?;
|
||||
@@ -70,32 +69,32 @@ impl MagiskInit {
|
||||
// /sdcard exists and fallback to using hexpatch.
|
||||
|
||||
if self.config.force_normal_boot {
|
||||
path!("/first_stage_ramdisk/storage/self")
|
||||
cstr!("/first_stage_ramdisk/storage/self")
|
||||
.mkdirs(0o755)
|
||||
.log_ok();
|
||||
path!("/first_stage_ramdisk/storage/self/primary")
|
||||
.create_symlink_to(path!("/system/system/bin/init"))
|
||||
cstr!("/first_stage_ramdisk/storage/self/primary")
|
||||
.create_symlink_to(cstr!("/system/system/bin/init"))
|
||||
.log_ok();
|
||||
debug!("Symlink /first_stage_ramdisk/storage/self/primary -> /system/system/bin/init");
|
||||
path!("/first_stage_ramdisk/sdcard")
|
||||
cstr!("/first_stage_ramdisk/sdcard")
|
||||
.create(O_RDONLY | O_CREAT | O_CLOEXEC, 0)
|
||||
.log_ok();
|
||||
} else {
|
||||
path!("/storage/self").mkdirs(0o755).log_ok();
|
||||
path!("/storage/self/primary")
|
||||
.create_symlink_to(path!("/system/system/bin/init"))
|
||||
cstr!("/storage/self").mkdirs(0o755).log_ok();
|
||||
cstr!("/storage/self/primary")
|
||||
.create_symlink_to(cstr!("/system/system/bin/init"))
|
||||
.log_ok();
|
||||
debug!("Symlink /storage/self/primary -> /system/system/bin/init");
|
||||
}
|
||||
path!("/init").rename_to(path!("/sdcard")).log_ok();
|
||||
cstr!("/init").rename_to(cstr!("/sdcard")).log_ok();
|
||||
|
||||
// First try to mount magiskinit from rootfs to workaround Samsung RKP
|
||||
if path!("/sdcard").bind_mount_to(path!("/sdcard")).is_ok() {
|
||||
if cstr!("/sdcard").bind_mount_to(cstr!("/sdcard")).is_ok() {
|
||||
debug!("Bind mount /sdcard -> /sdcard");
|
||||
} else {
|
||||
// Binding mounting from rootfs is not supported before Linux 3.12
|
||||
path!("/data/magiskinit")
|
||||
.bind_mount_to(path!("/sdcard"))
|
||||
cstr!("/data/magiskinit")
|
||||
.bind_mount_to(cstr!("/sdcard"))
|
||||
.log_ok();
|
||||
debug!("Bind mount /data/magiskinit -> /sdcard");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user