Skip to content

Commit e489b3b

Browse files
committed
Migrate load_modules to Rust
1 parent 589a270 commit e489b3b

4 files changed

Lines changed: 150 additions & 134 deletions

File tree

native/src/Android.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ LOCAL_SRC_FILES := \
2020
core/daemon.cpp \
2121
core/scripting.cpp \
2222
core/sqlite.cpp \
23-
core/module.cpp \
2423
core/thread.cpp \
2524
core/core-rs.cpp \
2625
core/resetprop/resetprop.cpp \

native/src/core/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ pub mod ffi {
158158
fn update_deny_flags(uid: i32, process: &str, flags: &mut u32);
159159
fn initialize_denylist();
160160
fn get_zygisk_lib_name() -> &'static str;
161+
fn set_zygisk_prop();
161162
fn restore_zygisk_prop();
162163
fn switch_mnt_ns(pid: i32) -> i32;
163164
fn app_request(req: &SuAppRequest) -> i32;
@@ -254,9 +255,6 @@ pub mod ffi {
254255
#[cxx_name = "Get"]
255256
fn get() -> &'static MagiskD;
256257
}
257-
unsafe extern "C++" {
258-
fn load_modules(self: &MagiskD) -> Vec<ModuleInfo>;
259-
}
260258
}
261259

262260
#[repr(transparent)]

native/src/core/module.cpp

Lines changed: 0 additions & 119 deletions
This file was deleted.

native/src/core/module.rs

Lines changed: 149 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
use crate::consts::{MODULEMNT, MODULEROOT, MODULEUPGRADE, WORKERDIR};
22
use crate::daemon::MagiskD;
3-
use crate::ffi::{ModuleInfo, exec_script, get_magisk_tmp, get_zygisk_lib_name, load_prop_file};
3+
use crate::ffi::{
4+
ModuleInfo, exec_module_scripts, exec_script, get_magisk_tmp, get_zygisk_lib_name,
5+
load_prop_file, set_zygisk_prop,
6+
};
47
use crate::mount::setup_module_mount;
58
use base::{
69
DirEntry, Directory, FsPathBuilder, LibcReturn, LoggedResult, OsResultStatic, ResultExt,
710
Utf8CStr, Utf8CStrBuf, Utf8CString, WalkResult, clone_attr, cstr, debug, error, info, libc,
8-
warn,
11+
raw_cstr, warn,
912
};
1013
use libc::{AT_REMOVEDIR, MS_RDONLY, O_CLOEXEC, O_CREAT, O_RDONLY};
1114
use std::collections::BTreeMap;
12-
use std::os::fd::AsRawFd;
15+
use std::os::fd::{AsRawFd, IntoRawFd};
1316
use std::path::{Component, Path};
17+
use std::ptr;
18+
use std::sync::atomic::Ordering;
1419

1520
const MAGISK_BIN_INJECT_PARTITIONS: [&Utf8CStr; 4] = [
1621
cstr!("/system/"),
@@ -698,7 +703,7 @@ fn upgrade_modules() -> LoggedResult<()> {
698703
Ok(())
699704
}
700705

701-
fn for_each_module(func: impl Fn(&DirEntry) -> LoggedResult<()>) -> LoggedResult<()> {
706+
fn for_each_module(mut func: impl FnMut(&DirEntry) -> LoggedResult<()>) -> LoggedResult<()> {
702707
let mut root = Directory::open(cstr!(MODULEROOT))?;
703708
while let Some(ref e) = root.read()? {
704709
if e.is_dir() && e.name() != ".core" {
@@ -717,28 +722,161 @@ pub fn disable_modules() {
717722
.log_ok();
718723
}
719724

725+
fn run_uninstall_script(module_name: &Utf8CStr) {
726+
let script = cstr::buf::default()
727+
.join_path(MODULEROOT)
728+
.join_path(module_name)
729+
.join_path("uninstall.sh");
730+
exec_script(&script);
731+
}
732+
720733
pub fn remove_modules() {
721734
for_each_module(|e| {
722735
let dir = e.open_as_dir()?;
723736
if dir.contains_path(cstr!("uninstall.sh")) {
724-
let script = cstr::buf::default()
725-
.join_path(MODULEROOT)
726-
.join_path(e.name())
727-
.join_path("uninstall.sh");
728-
exec_script(&script);
737+
run_uninstall_script(e.name());
729738
}
730739
Ok(())
731740
})
732741
.log_ok();
733742
cstr!(MODULEROOT).remove_all().log_ok();
734743
}
735744

745+
fn collect_modules(zygisk_enabled: bool, open_zygisk: bool) -> Vec<ModuleInfo> {
746+
let mut modules = Vec::new();
747+
748+
#[allow(unused_mut)] // It's possible that z32 and z64 are unused
749+
for_each_module(|e| {
750+
let name = e.name();
751+
let dir = e.open_as_dir()?;
752+
if dir.contains_path(cstr!("remove")) {
753+
info!("{name}: remove");
754+
if dir.contains_path(cstr!("uninstall.sh")) {
755+
run_uninstall_script(name);
756+
}
757+
dir.remove_all()?;
758+
e.unlink()?;
759+
return Ok(());
760+
}
761+
dir.unlink_at(cstr!("update"), 0).ok();
762+
if dir.contains_path(cstr!("disable")) {
763+
return Ok(());
764+
}
765+
766+
let mut z32 = -1;
767+
let mut z64 = -1;
768+
769+
let is_zygisk = dir.contains_path(cstr!("zygisk"));
770+
771+
if zygisk_enabled {
772+
// Riru and its modules are not compatible with zygisk
773+
if name == "riru-core" || dir.contains_path(cstr!("riru")) {
774+
return Ok(());
775+
}
776+
777+
fn open_fd_safe(dir: &Directory, name: &Utf8CStr) -> i32 {
778+
dir.open_as_file_at(name, O_RDONLY | O_CLOEXEC, 0)
779+
.log()
780+
.map(IntoRawFd::into_raw_fd)
781+
.unwrap_or(-1)
782+
}
783+
784+
if open_zygisk && is_zygisk {
785+
#[cfg(target_arch = "arm")]
786+
{
787+
z32 = open_fd_safe(&dir, cstr!("zygisk/armeabi-v7a.so"));
788+
}
789+
#[cfg(target_arch = "aarch64")]
790+
{
791+
z32 = open_fd_safe(&dir, cstr!("zygisk/armeabi-v7a.so"));
792+
z64 = open_fd_safe(&dir, cstr!("zygisk/arm64-v8a.so"));
793+
}
794+
#[cfg(target_arch = "x86")]
795+
{
796+
z32 = open_fd_safe(&dir, cstr!("zygisk/x86.so"));
797+
}
798+
#[cfg(target_arch = "x86_64")]
799+
{
800+
z32 = open_fd_safe(&dir, cstr!("zygisk/x86.so"));
801+
z64 = open_fd_safe(&dir, cstr!("zygisk/x86_64.so"));
802+
}
803+
#[cfg(target_arch = "riscv64")]
804+
{
805+
z64 = open_fd_safe(&dir, cstr!("zygisk/riscv64.so"));
806+
}
807+
dir.unlink_at(cstr!("zygisk/unloaded"), 0).ok();
808+
}
809+
} else {
810+
// Ignore zygisk modules when zygisk is not enabled
811+
if is_zygisk {
812+
info!("{name}: ignore");
813+
return Ok(());
814+
}
815+
}
816+
modules.push(ModuleInfo {
817+
name: name.to_string(),
818+
z32,
819+
z64,
820+
});
821+
Ok(())
822+
})
823+
.log_ok();
824+
825+
if zygisk_enabled && open_zygisk {
826+
let mut use_memfd = true;
827+
let mut convert_to_memfd = |fd: i32| -> i32 {
828+
if fd < 0 {
829+
return fd;
830+
}
831+
if use_memfd {
832+
let memfd = unsafe {
833+
libc::syscall(
834+
libc::SYS_memfd_create,
835+
raw_cstr!("jit-cache"),
836+
libc::MFD_CLOEXEC,
837+
) as i32
838+
};
839+
if memfd >= 0 {
840+
unsafe {
841+
if libc::sendfile(memfd, fd, ptr::null_mut(), i32::MAX as usize) < 0 {
842+
libc::close(memfd);
843+
} else {
844+
libc::close(fd);
845+
return memfd;
846+
}
847+
}
848+
}
849+
// Some error occurred, don't try again
850+
use_memfd = false;
851+
}
852+
fd
853+
};
854+
855+
modules.iter_mut().for_each(|m| {
856+
m.z32 = convert_to_memfd(m.z32);
857+
m.z64 = convert_to_memfd(m.z64);
858+
});
859+
}
860+
861+
modules
862+
}
863+
736864
impl MagiskD {
737865
pub fn handle_modules(&self) {
738866
setup_module_mount();
739867
upgrade_modules().ok();
740-
let modules = self.load_modules();
741-
apply_modules(self.zygisk_enabled(), &modules);
868+
869+
let zygisk = self.zygisk_enabled.load(Ordering::Acquire);
870+
let modules = collect_modules(zygisk, false);
871+
exec_module_scripts(cstr!("post-fs-data"), &modules);
872+
873+
// Recollect modules (module scripts could remove itself)
874+
let modules = collect_modules(zygisk, true);
875+
if zygisk {
876+
set_zygisk_prop();
877+
}
878+
apply_modules(zygisk, &modules);
879+
742880
self.module_list.set(modules).ok();
743881
}
744882
}

0 commit comments

Comments
 (0)