Partially cleanup MagiskInit code

This commit is contained in:
topjohnwu
2025-02-14 23:52:56 -08:00
committed by John Wu
parent 4d80361805
commit 3c7c46307a
9 changed files with 73 additions and 56 deletions

View File

@@ -1,5 +1,5 @@
use crate::ffi::{BootConfig, MagiskInit}; use crate::ffi::{backup_init, BootConfig, MagiskInit};
use base::{cstr, debug, BytesExt, FsPath, MappedFile, Utf8CStr}; use base::{cstr, debug, BytesExt, FsPath, MappedFile};
use std::ffi::CStr; use std::ffi::CStr;
impl BootConfig { impl BootConfig {
@@ -33,6 +33,8 @@ impl MagiskInit {
// Use the apex folder to determine whether 2SI (Android 10+) // Use the apex folder to determine whether 2SI (Android 10+)
FsPath::from(cstr!("/apex")).exists() || FsPath::from(cstr!("/apex")).exists() ||
// If we still have no indication, parse the original init and see what's up // 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)
} }
} }

View File

@@ -1,10 +1,10 @@
#include <base.hpp> #include <base.hpp>
#include <stream.hpp> #include <stream.hpp>
#include "init-rs.hpp"
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android" #define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
#define INIT_PATH "/system/bin/init"
#define REDIR_PATH "/data/magiskinit" #define REDIR_PATH "/data/magiskinit"
int magisk_proxy_main(int argc, char *argv[]); int magisk_proxy_main(int, char *argv[]);
rust::Utf8CStr backup_init();
#include "init-rs.hpp"

View File

@@ -1,3 +1,4 @@
use crate::ffi::backup_init;
use crate::{ use crate::{
ffi::{magisk_proxy_main, BootConfig, MagiskInit}, ffi::{magisk_proxy_main, BootConfig, MagiskInit},
logging::setup_klog, logging::setup_klog,
@@ -5,7 +6,7 @@ use crate::{
use base::{ use base::{
cstr, debug, info, cstr, debug, info,
libc::{basename, getpid, mount, umask}, libc::{basename, getpid, mount, umask},
raw_cstr, FsPath, LibcReturn, LoggedResult, ResultExt, Utf8CStr, raw_cstr, FsPath, LibcReturn, LoggedResult, ResultExt,
}; };
use std::{ use std::{
ffi::{c_char, CStr}, ffi::{c_char, CStr},
@@ -63,7 +64,7 @@ impl MagiskInit {
pub(crate) fn restore_ramdisk_init(&self) { pub(crate) fn restore_ramdisk_init(&self) {
FsPath::from(cstr!("/init")).remove().ok(); 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() { if orig_init.exists() {
orig_init.rename_to(FsPath::from(cstr!("/init"))).log_ok(); orig_init.rename_to(FsPath::from(cstr!("/init"))).log_ok();

View File

@@ -1,20 +1,21 @@
#![feature(format_args_nl)] #![feature(format_args_nl)]
#![feature(once_cell_try)] #![feature(once_cell_try)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![allow(clippy::missing_safety_doc)]
use logging::setup_klog; 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 // Has to be pub so all symbols in that crate is included
pub use magiskpolicy; 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 logging;
mod mount; mod mount;
mod rootdir; mod rootdir;
mod getinfo;
mod init;
mod twostage;
mod selinux; mod selinux;
mod twostage;
#[cxx::bridge] #[cxx::bridge]
pub mod ffi { pub mod ffi {
@@ -23,6 +24,7 @@ pub mod ffi {
key: String, key: String,
value: String, value: String,
} }
struct BootConfig { struct BootConfig {
skip_initramfs: bool, skip_initramfs: bool,
force_normal_boot: bool, force_normal_boot: bool,
@@ -43,6 +45,17 @@ pub mod ffi {
config: BootConfig, 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"] #[namespace = "rust"]
extern "Rust" { extern "Rust" {
fn setup_klog(); fn setup_klog();
@@ -53,39 +66,32 @@ pub mod ffi {
fn reset_overlay_contexts(); fn reset_overlay_contexts();
} }
// BootConfig
extern "Rust" { extern "Rust" {
fn print(self: &BootConfig); fn print(self: &BootConfig);
fn patch_sepolicy(self: &MagiskInit, in_: Utf8CStrRef, out: Utf8CStrRef);
} }
unsafe extern "C++" { 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); fn init(self: &mut BootConfig);
type kv_pairs; type kv_pairs;
fn set(self: &mut BootConfig, config: &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); unsafe fn setup_tmp(self: &MagiskInit, path: *const c_char);
fn collect_devices(self: &MagiskInit); fn collect_devices(self: &MagiskInit);
fn mount_preinit_dir(self: &MagiskInit); fn mount_preinit_dir(self: &MagiskInit);
unsafe fn find_block(self: &MagiskInit, partname: *const c_char) -> u64; 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 hijack_sepolicy(self: &mut MagiskInit) -> bool;
fn backup_init(self: &MagiskInit) -> *const c_char;
} }
} }

View File

@@ -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 { void MagiskInit::patch_ro_root() noexcept {
mount_list.emplace_back("/data"); mount_list.emplace_back("/data");
parse_config_file(); parse_config_file();
@@ -427,7 +417,7 @@ void MagiskInit::patch_rw_root() noexcept {
cp_afc(REDIR_PATH, "/sbin/magisk"); cp_afc(REDIR_PATH, "/sbin/magisk");
} }
int magisk_proxy_main(int argc, char *argv[]) { int magisk_proxy_main(int, char *argv[]) {
rust::setup_klog(); rust::setup_klog();
LOGD("%s\n", __FUNCTION__); LOGD("%s\n", __FUNCTION__);
@@ -463,7 +453,7 @@ static void unxz_init(const char *init_xz, const char *init) {
unlink(init_xz); unlink(init_xz);
} }
const char *MagiskInit::backup_init() const noexcept { rust::Utf8CStr backup_init() {
if (access("/.backup/init.xz", F_OK) == 0) if (access("/.backup/init.xz", F_OK) == 0)
unxz_init("/.backup/init.xz", "/.backup/init"); unxz_init("/.backup/init.xz", "/.backup/init");
return "/.backup/init"; return "/.backup/init";

View File

@@ -1,7 +1,10 @@
use crate::ffi::MagiskInit;
use base::libc::O_RDONLY;
use base::{ use base::{
debug, libc, Directory, LibcReturn, LoggedResult, ResultExt, Utf8CStr, Utf8CStrBuf, cstr, debug, libc, BufReadExt, Directory, FsPath, LibcReturn, LoggedResult, ResultExt,
Utf8CStrBufArr, WalkResult, Utf8CStr, Utf8CStrBuf, Utf8CStrBufArr, WalkResult,
}; };
use std::io::BufReader;
use std::{ use std::{
fs::File, fs::File,
io::Write, io::Write,
@@ -110,3 +113,18 @@ on property:init.svc.zygote=stopped
mem::forget(file) 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
})
}
}
}

View File

@@ -1,11 +1,11 @@
use crate::ffi::MagiskInit; use crate::ffi::MagiskInit;
use base::{cstr, debug, ffi::Utf8CStrRef, FsPath}; use base::{cstr, debug, FsPath, Utf8CStr};
use magiskpolicy::ffi::SePolicy; use magiskpolicy::ffi::SePolicy;
impl MagiskInit { 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"); debug!("Patching monolithic policy");
let mut sepol = SePolicy::from_file(in_); let mut sepol = SePolicy::from_file(src);
sepol.magisk_rules(); sepol.magisk_rules();

View File

@@ -78,7 +78,7 @@ pub mod ffi {
#[Self = SePolicy] #[Self = SePolicy]
fn compile_split() -> SePolicy; fn compile_split() -> SePolicy;
#[Self = SePolicy] #[Self = SePolicy]
unsafe fn from_data(data: *mut c_char, len: usize) -> SePolicy; fn from_data(data: &[u8]) -> SePolicy;
} }
extern "Rust" { extern "Rust" {

View File

@@ -79,13 +79,13 @@ static void load_cil(struct cil_db *db, const char *file) {
LOGD("cil_add [%s]\n", file); LOGD("cil_add [%s]\n", file);
} }
SePolicy SePolicy::from_data(char *data, size_t len) noexcept { SePolicy SePolicy::from_data(rust::Slice<const uint8_t> data) noexcept {
LOGD("Load policy from data\n"); LOGD("Load policy from data\n");
policy_file_t pf; policy_file_t pf;
policy_file_init(&pf); policy_file_init(&pf);
pf.data = data; pf.data = (char *) data.data();
pf.len = len; pf.len = data.size();
pf.type = PF_USE_MEMORY; pf.type = PF_USE_MEMORY;
auto db = static_cast<policydb_t *>(malloc(sizeof(policydb_t))); auto db = static_cast<policydb_t *>(malloc(sizeof(policydb_t)));