diff --git a/native/src/Android.mk b/native/src/Android.mk index 3fb9a5d37..856c41254 100644 --- a/native/src/Android.mk +++ b/native/src/Android.mk @@ -66,7 +66,6 @@ LOCAL_SRC_FILES := \ init/mount.cpp \ init/rootdir.cpp \ init/getinfo.cpp \ - init/twostage.cpp \ init/selinux.cpp \ init/init-rs.cpp diff --git a/native/src/init/lib.rs b/native/src/init/lib.rs index 04672c8e5..f6feb7c78 100644 --- a/native/src/init/lib.rs +++ b/native/src/init/lib.rs @@ -84,9 +84,6 @@ pub mod ffi { fn patch_rw_root(self: &mut MagiskInit); fn patch_ro_root(self: &mut MagiskInit); - // Two stage init - fn redirect_second_stage(self: &MagiskInit); - // SELinux unsafe fn patch_sepolicy(self: &MagiskInit, in_: *const c_char, out: *const c_char); fn hijack_sepolicy(self: &mut MagiskInit) -> bool; diff --git a/native/src/init/twostage.cpp b/native/src/init/twostage.cpp deleted file mode 100644 index b4b6626bb..000000000 --- a/native/src/init/twostage.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include - -#include -#include -#include - -#include "init.hpp" - -using namespace std; - -void MagiskInit::redirect_second_stage() const noexcept { - // Patch init binary - int src = xopen("/init", O_RDONLY); - int dest = xopen("/data/init", O_CREAT | O_WRONLY, 0); - { - mmap_data init("/init"); - for (size_t off : init.patch(INIT_PATH, REDIR_PATH)) { - LOGD("Patch @ %08zX [" INIT_PATH "] -> [" REDIR_PATH "]\n", off); - } - write(dest, init.buf(), init.sz()); - fclone_attr(src, dest); - close(dest); - close(src); - } - xmount("/data/init", "/init", nullptr, MS_BIND, nullptr); -} diff --git a/native/src/init/twostage.rs b/native/src/init/twostage.rs index a366f673a..c3f28a24e 100644 --- a/native/src/init/twostage.rs +++ b/native/src/init/twostage.rs @@ -1,14 +1,15 @@ use crate::ffi::MagiskInit; -use base::libc::{mount, MS_BIND}; +use base::libc::{mount, MS_BIND, O_WRONLY}; use base::{ - cstr, debug, info, + clone_attr, cstr, debug, error, info, libc::{ fstatat, stat, statfs, umount2, AT_SYMLINK_NOFOLLOW, MNT_DETACH, O_CLOEXEC, O_CREAT, O_RDONLY, TMPFS_MAGIC, }, - raw_cstr, FsPath, MappedFile, MutBytesExt, ResultExt, + raw_cstr, FsPath, LibcReturn, MappedFile, MutBytesExt, ResultExt, }; use std::ffi::c_long; +use std::io::Write; use std::ptr::null; impl MagiskInit { @@ -17,7 +18,7 @@ impl MagiskInit { self.prepare_data(); if unsafe { - let mut st: stat = unsafe { std::mem::zeroed() }; + let mut st: stat = std::mem::zeroed(); fstatat( -1, raw_cstr!("/sdcard"), @@ -104,11 +105,40 @@ impl MagiskInit { debug!("Patch @ {:#010X} [{}] -> [{}]", off, from, to); } } else { - debug!("Failed to open /init for hexpatch"); + error!("Failed to open /init for hexpatch"); } } } + pub(crate) fn redirect_second_stage(&self) { + let src = FsPath::from(cstr!("/init")); + let dest = FsPath::from(cstr!("/data/init")); + // Patch init binary + if let Ok(mut map) = MappedFile::open(src) { + let from = "/system/bin/init"; + let to = "/data/magiskinit"; + + // Redirect original init to magiskinit + let v = map.patch(from.as_bytes(), to.as_bytes()); + for off in &v { + debug!("Patch @ {:#010X} [{}] -> [{}]", off, from, to); + } + if let Ok(mut dest) = dest.create(O_CREAT | O_WRONLY, 0) { + dest.write_all(map.as_ref()).log().ok(); + } else { + error!("Failed to create {}", dest); + } + } else { + error!("Failed to open {} for hexpatch", src); + } + clone_attr(src, dest).log().ok(); + unsafe { + mount(dest.as_ptr(), src.as_ptr(), null(), MS_BIND, null()) + .as_os_err() + .ok(); + } + } + pub(crate) fn second_stage(&mut self) { info!("Second Stage Init"); unsafe {