From 3c7c46307af444b205547375a98382db7fb3185d Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 14 Feb 2025 23:52:56 -0800 Subject: [PATCH] Partially cleanup MagiskInit code --- native/src/init/getinfo.rs | 8 +++-- native/src/init/init.hpp | 8 ++--- native/src/init/init.rs | 5 +-- native/src/init/lib.rs | 58 ++++++++++++++++++-------------- native/src/init/rootdir.cpp | 14 ++------ native/src/init/rootdir.rs | 22 ++++++++++-- native/src/init/selinux.rs | 6 ++-- native/src/sepolicy/lib.rs | 2 +- native/src/sepolicy/policydb.cpp | 6 ++-- 9 files changed, 73 insertions(+), 56 deletions(-) diff --git a/native/src/init/getinfo.rs b/native/src/init/getinfo.rs index fc1f57052..00f7ec589 100644 --- a/native/src/init/getinfo.rs +++ b/native/src/init/getinfo.rs @@ -1,5 +1,5 @@ -use crate::ffi::{BootConfig, MagiskInit}; -use base::{cstr, debug, BytesExt, FsPath, MappedFile, Utf8CStr}; +use crate::ffi::{backup_init, BootConfig, MagiskInit}; +use base::{cstr, debug, BytesExt, FsPath, MappedFile}; use std::ffi::CStr; impl BootConfig { @@ -33,6 +33,8 @@ impl MagiskInit { // Use the apex folder to determine whether 2SI (Android 10+) FsPath::from(cstr!("/apex")).exists() || // If we still have no indication, parse the original init and see what's up - MappedFile::open(unsafe { Utf8CStr::from_ptr_unchecked(self.backup_init()) }).map(|map| map.contains(b"selinux_setup")).unwrap_or(false) + MappedFile::open(backup_init()) + .map(|data| data.contains(b"selinux_setup")) + .unwrap_or(false) } } diff --git a/native/src/init/init.hpp b/native/src/init/init.hpp index 7ebbbb187..656b05d46 100644 --- a/native/src/init/init.hpp +++ b/native/src/init/init.hpp @@ -1,10 +1,10 @@ #include #include +#include "init-rs.hpp" + #define DEFAULT_DT_DIR "/proc/device-tree/firmware/android" -#define INIT_PATH "/system/bin/init" #define REDIR_PATH "/data/magiskinit" -int magisk_proxy_main(int argc, char *argv[]); - -#include "init-rs.hpp" +int magisk_proxy_main(int, char *argv[]); +rust::Utf8CStr backup_init(); diff --git a/native/src/init/init.rs b/native/src/init/init.rs index aba4beee7..75671bb65 100644 --- a/native/src/init/init.rs +++ b/native/src/init/init.rs @@ -1,3 +1,4 @@ +use crate::ffi::backup_init; use crate::{ ffi::{magisk_proxy_main, BootConfig, MagiskInit}, logging::setup_klog, @@ -5,7 +6,7 @@ use crate::{ use base::{ cstr, debug, info, libc::{basename, getpid, mount, umask}, - raw_cstr, FsPath, LibcReturn, LoggedResult, ResultExt, Utf8CStr, + raw_cstr, FsPath, LibcReturn, LoggedResult, ResultExt, }; use std::{ ffi::{c_char, CStr}, @@ -63,7 +64,7 @@ impl MagiskInit { pub(crate) fn restore_ramdisk_init(&self) { FsPath::from(cstr!("/init")).remove().ok(); - let orig_init = FsPath::from(unsafe { Utf8CStr::from_ptr_unchecked(self.backup_init()) }); + let orig_init = FsPath::from(backup_init()); if orig_init.exists() { orig_init.rename_to(FsPath::from(cstr!("/init"))).log_ok(); diff --git a/native/src/init/lib.rs b/native/src/init/lib.rs index 20927c7bd..a14f45c7b 100644 --- a/native/src/init/lib.rs +++ b/native/src/init/lib.rs @@ -1,20 +1,21 @@ #![feature(format_args_nl)] #![feature(once_cell_try)] #![feature(try_blocks)] +#![allow(clippy::missing_safety_doc)] use logging::setup_klog; -use mount::{is_device_mounted, switch_root}; -use rootdir::{collect_overlay_contexts, inject_magisk_rc, reset_overlay_contexts}; // Has to be pub so all symbols in that crate is included pub use magiskpolicy; +use mount::{is_device_mounted, switch_root}; +use rootdir::{collect_overlay_contexts, inject_magisk_rc, reset_overlay_contexts}; +mod getinfo; +mod init; mod logging; mod mount; mod rootdir; -mod getinfo; -mod init; -mod twostage; mod selinux; +mod twostage; #[cxx::bridge] pub mod ffi { @@ -23,6 +24,7 @@ pub mod ffi { key: String, value: String, } + struct BootConfig { skip_initramfs: bool, force_normal_boot: bool, @@ -43,6 +45,17 @@ pub mod ffi { config: BootConfig, } + unsafe extern "C++" { + include!("init.hpp"); + + #[namespace = "rust"] + #[cxx_name = "Utf8CStr"] + type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>; + + unsafe fn magisk_proxy_main(argc: i32, argv: *mut *mut c_char) -> i32; + fn backup_init() -> Utf8CStrRef<'static>; + } + #[namespace = "rust"] extern "Rust" { fn setup_klog(); @@ -53,39 +66,32 @@ pub mod ffi { fn reset_overlay_contexts(); } + // BootConfig extern "Rust" { fn print(self: &BootConfig); - - fn patch_sepolicy(self: &MagiskInit, in_: Utf8CStrRef, out: Utf8CStrRef); } - unsafe extern "C++" { - include!("../base/include/base.hpp"); - include!("init.hpp"); - - #[namespace = "rust"] - #[cxx_name = "Utf8CStr"] - type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>; - - unsafe fn magisk_proxy_main(argc: i32, argv: *mut *mut c_char) -> i32; - fn init(self: &mut BootConfig); type kv_pairs; fn set(self: &mut BootConfig, config: &kv_pairs); + } + // MagiskInit + extern "Rust" { + fn patch_sepolicy(self: &MagiskInit, src: Utf8CStrRef, out: Utf8CStrRef); + fn parse_config_file(self: &mut MagiskInit); + } + unsafe extern "C++" { + // Used in Rust + fn mount_system_root(self: &mut MagiskInit) -> bool; + fn patch_rw_root(self: &mut MagiskInit); + fn patch_ro_root(self: &mut MagiskInit); + + // Used in C++ unsafe fn setup_tmp(self: &MagiskInit, path: *const c_char); fn collect_devices(self: &MagiskInit); fn mount_preinit_dir(self: &MagiskInit); unsafe fn find_block(self: &MagiskInit, partname: *const c_char) -> u64; - fn mount_system_root(self: &mut MagiskInit) -> bool; - - // Setup and patch root directory - fn parse_config_file(self: &mut MagiskInit); - fn patch_rw_root(self: &mut MagiskInit); - fn patch_ro_root(self: &mut MagiskInit); - - // SELinux fn hijack_sepolicy(self: &mut MagiskInit) -> bool; - fn backup_init(self: &MagiskInit) -> *const c_char; } } diff --git a/native/src/init/rootdir.cpp b/native/src/init/rootdir.cpp index c5aa2da5e..93446614f 100644 --- a/native/src/init/rootdir.cpp +++ b/native/src/init/rootdir.cpp @@ -283,16 +283,6 @@ static void extract_files(bool sbin) { } } -void MagiskInit::parse_config_file() noexcept { - parse_prop_file("/data/.backup/.magisk", [&](auto key, auto value) -> bool { - if (key == "PREINITDEVICE") { - preinit_dev = std::string(value); - return false; - } - return true; - }); -} - void MagiskInit::patch_ro_root() noexcept { mount_list.emplace_back("/data"); parse_config_file(); @@ -427,7 +417,7 @@ void MagiskInit::patch_rw_root() noexcept { cp_afc(REDIR_PATH, "/sbin/magisk"); } -int magisk_proxy_main(int argc, char *argv[]) { +int magisk_proxy_main(int, char *argv[]) { rust::setup_klog(); LOGD("%s\n", __FUNCTION__); @@ -463,7 +453,7 @@ static void unxz_init(const char *init_xz, const char *init) { unlink(init_xz); } -const char *MagiskInit::backup_init() const noexcept { +rust::Utf8CStr backup_init() { if (access("/.backup/init.xz", F_OK) == 0) unxz_init("/.backup/init.xz", "/.backup/init"); return "/.backup/init"; diff --git a/native/src/init/rootdir.rs b/native/src/init/rootdir.rs index 24486a649..9b3b817a8 100644 --- a/native/src/init/rootdir.rs +++ b/native/src/init/rootdir.rs @@ -1,7 +1,10 @@ +use crate::ffi::MagiskInit; +use base::libc::O_RDONLY; use base::{ - debug, libc, Directory, LibcReturn, LoggedResult, ResultExt, Utf8CStr, Utf8CStrBuf, - Utf8CStrBufArr, WalkResult, + cstr, debug, libc, BufReadExt, Directory, FsPath, LibcReturn, LoggedResult, ResultExt, + Utf8CStr, Utf8CStrBuf, Utf8CStrBufArr, WalkResult, }; +use std::io::BufReader; use std::{ fs::File, io::Write, @@ -110,3 +113,18 @@ on property:init.svc.zygote=stopped mem::forget(file) } + +impl MagiskInit { + pub(crate) fn parse_config_file(&mut self) { + if let Ok(fd) = FsPath::from(cstr!("/data/.backup/.magisk")).open(O_RDONLY) { + let mut reader = BufReader::new(fd); + reader.foreach_props(|key, val| { + if key == "PREINITDEVICE" { + self.preinit_dev = val.to_string(); + return false; + } + true + }) + } + } +} diff --git a/native/src/init/selinux.rs b/native/src/init/selinux.rs index c5e11d8b3..b94fd0b23 100644 --- a/native/src/init/selinux.rs +++ b/native/src/init/selinux.rs @@ -1,11 +1,11 @@ use crate::ffi::MagiskInit; -use base::{cstr, debug, ffi::Utf8CStrRef, FsPath}; +use base::{cstr, debug, FsPath, Utf8CStr}; use magiskpolicy::ffi::SePolicy; impl MagiskInit { - pub(crate) fn patch_sepolicy(self: &MagiskInit, in_: Utf8CStrRef, out: Utf8CStrRef) { + pub(crate) fn patch_sepolicy(self: &MagiskInit, src: &Utf8CStr, out: &Utf8CStr) { debug!("Patching monolithic policy"); - let mut sepol = SePolicy::from_file(in_); + let mut sepol = SePolicy::from_file(src); sepol.magisk_rules(); diff --git a/native/src/sepolicy/lib.rs b/native/src/sepolicy/lib.rs index 1d1f6ebc0..51efcfa66 100644 --- a/native/src/sepolicy/lib.rs +++ b/native/src/sepolicy/lib.rs @@ -78,7 +78,7 @@ pub mod ffi { #[Self = SePolicy] fn compile_split() -> SePolicy; #[Self = SePolicy] - unsafe fn from_data(data: *mut c_char, len: usize) -> SePolicy; + fn from_data(data: &[u8]) -> SePolicy; } extern "Rust" { diff --git a/native/src/sepolicy/policydb.cpp b/native/src/sepolicy/policydb.cpp index 78f75f5aa..0c2e32507 100644 --- a/native/src/sepolicy/policydb.cpp +++ b/native/src/sepolicy/policydb.cpp @@ -79,13 +79,13 @@ static void load_cil(struct cil_db *db, const char *file) { LOGD("cil_add [%s]\n", file); } -SePolicy SePolicy::from_data(char *data, size_t len) noexcept { +SePolicy SePolicy::from_data(rust::Slice data) noexcept { LOGD("Load policy from data\n"); policy_file_t pf; policy_file_init(&pf); - pf.data = data; - pf.len = len; + pf.data = (char *) data.data(); + pf.len = data.size(); pf.type = PF_USE_MEMORY; auto db = static_cast(malloc(sizeof(policydb_t)));