mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-22 10:28:30 +00:00
Fully implement daemon side of Zygisk in Rust
This commit is contained in:
parent
b575c95710
commit
15a605765c
@ -8,6 +8,7 @@ use num_traits::FromPrimitive;
|
|||||||
|
|
||||||
pub use cstr::*;
|
pub use cstr::*;
|
||||||
use cxx_extern::*;
|
use cxx_extern::*;
|
||||||
|
pub use ffi::fork_dont_care;
|
||||||
pub use files::*;
|
pub use files::*;
|
||||||
pub use logging::*;
|
pub use logging::*;
|
||||||
pub use misc::*;
|
pub use misc::*;
|
||||||
@ -42,6 +43,7 @@ pub mod ffi {
|
|||||||
type Utf8CStrRef<'a> = &'a crate::cstr::Utf8CStr;
|
type Utf8CStrRef<'a> = &'a crate::cstr::Utf8CStr;
|
||||||
|
|
||||||
fn mut_u8_patch(buf: &mut [u8], from: &[u8], to: &[u8]) -> Vec<usize>;
|
fn mut_u8_patch(buf: &mut [u8], from: &[u8], to: &[u8]) -> Vec<usize>;
|
||||||
|
fn fork_dont_care() -> i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool zygisk_enabled = false;
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
* Setup *
|
* Setup *
|
||||||
*********/
|
*********/
|
||||||
@ -175,10 +173,6 @@ bool MagiskD::post_fs_data() const noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exec_common_scripts("post-fs-data");
|
exec_common_scripts("post-fs-data");
|
||||||
zygisk_enabled = get_db_setting(DbEntryKey::ZygiskConfig);
|
|
||||||
initialize_denylist();
|
|
||||||
setup_mounts();
|
|
||||||
handle_modules();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,5 +200,5 @@ void MagiskD::boot_complete() const noexcept {
|
|||||||
// Ensure manager exists
|
// Ensure manager exists
|
||||||
get_manager(0, nullptr, true);
|
get_manager(0, nullptr, true);
|
||||||
|
|
||||||
reset_zygisk(true);
|
zygisk_reset(true);
|
||||||
}
|
}
|
||||||
|
@ -142,13 +142,15 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
|
|||||||
case +RequestCode::SUPERUSER:
|
case +RequestCode::SUPERUSER:
|
||||||
su_daemon_handler(client, &cred);
|
su_daemon_handler(client, &cred);
|
||||||
break;
|
break;
|
||||||
case +RequestCode::ZYGOTE_RESTART:
|
case +RequestCode::ZYGOTE_RESTART: {
|
||||||
LOGI("** zygote restarted\n");
|
LOGI("** zygote restarted\n");
|
||||||
MagiskD().prune_su_access();
|
auto &daemon = MagiskD();
|
||||||
|
daemon.prune_su_access();
|
||||||
scan_deny_apps();
|
scan_deny_apps();
|
||||||
reset_zygisk(false);
|
daemon.zygisk_reset(false);
|
||||||
close(client);
|
close(client);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case +RequestCode::SQLITE_CMD:
|
case +RequestCode::SQLITE_CMD:
|
||||||
MagiskD().db_exec(client);
|
MagiskD().db_exec(client);
|
||||||
break;
|
break;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::consts::{MAGISK_FULL_VER, MAIN_CONFIG};
|
use crate::consts::{MAGISK_FULL_VER, MAIN_CONFIG};
|
||||||
use crate::db::Sqlite3;
|
use crate::db::Sqlite3;
|
||||||
use crate::ffi::{get_magisk_tmp, ModuleInfo, RequestCode};
|
use crate::ffi::{get_magisk_tmp, initialize_denylist, DbEntryKey, ModuleInfo, RequestCode};
|
||||||
use crate::get_prop;
|
use crate::get_prop;
|
||||||
use crate::logging::{magisk_logging, start_log_daemon};
|
use crate::logging::{magisk_logging, start_log_daemon};
|
||||||
|
use crate::mount::setup_mounts;
|
||||||
use crate::package::ManagerInfo;
|
use crate::package::ManagerInfo;
|
||||||
use base::libc::{O_CLOEXEC, O_RDONLY};
|
use base::libc::{O_CLOEXEC, O_RDONLY};
|
||||||
use base::{
|
use base::{
|
||||||
@ -17,6 +18,7 @@ use std::io::{BufReader, ErrorKind, IoSlice, IoSliceMut, Read, Write};
|
|||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::os::fd::{FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
use std::os::fd::{FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||||
use std::os::unix::net::{AncillaryData, SocketAncillary, UnixStream};
|
use std::os::unix::net::{AncillaryData, SocketAncillary, UnixStream};
|
||||||
|
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||||
use std::sync::{Mutex, OnceLock};
|
use std::sync::{Mutex, OnceLock};
|
||||||
|
|
||||||
// Global magiskd singleton
|
// Global magiskd singleton
|
||||||
@ -64,6 +66,9 @@ pub struct MagiskD {
|
|||||||
pub manager_info: Mutex<ManagerInfo>,
|
pub manager_info: Mutex<ManagerInfo>,
|
||||||
boot_stage_lock: Mutex<BootStateFlags>,
|
boot_stage_lock: Mutex<BootStateFlags>,
|
||||||
pub module_list: OnceLock<Vec<ModuleInfo>>,
|
pub module_list: OnceLock<Vec<ModuleInfo>>,
|
||||||
|
pub zygiskd_sockets: Mutex<(Option<UnixStream>, Option<UnixStream>)>,
|
||||||
|
pub zygisk_enabled: AtomicBool,
|
||||||
|
pub zygote_start_count: AtomicU32,
|
||||||
sdk_int: i32,
|
sdk_int: i32,
|
||||||
pub is_emulator: bool,
|
pub is_emulator: bool,
|
||||||
is_recovery: bool,
|
is_recovery: bool,
|
||||||
@ -74,6 +79,10 @@ impl MagiskD {
|
|||||||
self.is_recovery
|
self.is_recovery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn zygisk_enabled(&self) -> bool {
|
||||||
|
self.zygisk_enabled.load(Ordering::Acquire)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sdk_int(&self) -> i32 {
|
pub fn sdk_int(&self) -> i32 {
|
||||||
self.sdk_int
|
self.sdk_int
|
||||||
}
|
}
|
||||||
@ -139,6 +148,14 @@ impl MagiskD {
|
|||||||
if check_data() && !state.contains(BootState::PostFsDataDone) {
|
if check_data() && !state.contains(BootState::PostFsDataDone) {
|
||||||
if self.post_fs_data() {
|
if self.post_fs_data() {
|
||||||
state.set(BootState::SafeMode);
|
state.set(BootState::SafeMode);
|
||||||
|
} else {
|
||||||
|
self.zygisk_enabled.store(
|
||||||
|
self.get_db_setting(DbEntryKey::ZygiskConfig) != 0,
|
||||||
|
Ordering::Release,
|
||||||
|
);
|
||||||
|
initialize_denylist();
|
||||||
|
setup_mounts();
|
||||||
|
self.handle_modules();
|
||||||
}
|
}
|
||||||
state.set(BootState::PostFsDataDone);
|
state.set(BootState::PostFsDataDone);
|
||||||
}
|
}
|
||||||
@ -215,6 +232,7 @@ pub fn daemon_entry() {
|
|||||||
sdk_int,
|
sdk_int,
|
||||||
is_emulator,
|
is_emulator,
|
||||||
is_recovery,
|
is_recovery,
|
||||||
|
zygote_start_count: AtomicU32::new(1),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
MAGISKD.set(magiskd).ok();
|
MAGISKD.set(magiskd).ok();
|
||||||
|
@ -370,7 +370,7 @@ int enable_deny() {
|
|||||||
|
|
||||||
denylist_enforced = true;
|
denylist_enforced = true;
|
||||||
|
|
||||||
if (!zygisk_enabled) {
|
if (!MagiskD().zygisk_enabled()) {
|
||||||
if (new_daemon_thread(&logcat)) {
|
if (new_daemon_thread(&logcat)) {
|
||||||
denylist_enforced = false;
|
denylist_enforced = false;
|
||||||
return DenyResponse::ERROR;
|
return DenyResponse::ERROR;
|
||||||
|
@ -26,7 +26,6 @@ enum class RespondCode : int {
|
|||||||
END
|
END
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool zygisk_enabled;
|
|
||||||
extern std::string native_bridge;
|
extern std::string native_bridge;
|
||||||
|
|
||||||
void reset_zygisk(bool restore);
|
void reset_zygisk(bool restore);
|
||||||
|
@ -6,6 +6,8 @@ const char *get_magisk_tmp();
|
|||||||
void install_apk(rust::Utf8CStr apk);
|
void install_apk(rust::Utf8CStr apk);
|
||||||
void uninstall_pkg(rust::Utf8CStr pkg);
|
void uninstall_pkg(rust::Utf8CStr pkg);
|
||||||
void update_deny_flags(int uid, rust::Str process, uint32_t &flags);
|
void update_deny_flags(int uid, rust::Str process, uint32_t &flags);
|
||||||
|
void initialize_denylist();
|
||||||
|
void restore_zygisk_prop();
|
||||||
|
|
||||||
// Rust bindings
|
// Rust bindings
|
||||||
static inline rust::Utf8CStr get_magisk_tmp_rs() { return get_magisk_tmp(); }
|
static inline rust::Utf8CStr get_magisk_tmp_rs() { return get_magisk_tmp(); }
|
||||||
|
@ -81,6 +81,8 @@ pub mod ffi {
|
|||||||
fn install_apk(apk: Utf8CStrRef);
|
fn install_apk(apk: Utf8CStrRef);
|
||||||
fn uninstall_pkg(apk: Utf8CStrRef);
|
fn uninstall_pkg(apk: Utf8CStrRef);
|
||||||
fn update_deny_flags(uid: i32, process: &str, flags: &mut u32);
|
fn update_deny_flags(uid: i32, process: &str, flags: &mut u32);
|
||||||
|
fn initialize_denylist();
|
||||||
|
fn restore_zygisk_prop();
|
||||||
fn switch_mnt_ns(pid: i32) -> i32;
|
fn switch_mnt_ns(pid: i32) -> i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +188,6 @@ pub mod ffi {
|
|||||||
fn zygisk_close_logd();
|
fn zygisk_close_logd();
|
||||||
fn zygisk_get_logd() -> i32;
|
fn zygisk_get_logd() -> i32;
|
||||||
fn setup_logfile();
|
fn setup_logfile();
|
||||||
fn setup_mounts();
|
|
||||||
fn clean_mounts();
|
fn clean_mounts();
|
||||||
fn find_preinit_device() -> String;
|
fn find_preinit_device() -> String;
|
||||||
fn revert_unmount(pid: i32);
|
fn revert_unmount(pid: i32);
|
||||||
@ -209,15 +210,16 @@ pub mod ffi {
|
|||||||
type MagiskD;
|
type MagiskD;
|
||||||
fn is_recovery(&self) -> bool;
|
fn is_recovery(&self) -> bool;
|
||||||
fn sdk_int(&self) -> i32;
|
fn sdk_int(&self) -> i32;
|
||||||
|
fn zygisk_enabled(&self) -> bool;
|
||||||
fn boot_stage_handler(&self, client: i32, code: i32);
|
fn boot_stage_handler(&self, client: i32, code: i32);
|
||||||
fn zygisk_handler(&self, client: i32);
|
fn zygisk_handler(&self, client: i32);
|
||||||
|
fn zygisk_reset(&self, restore: bool);
|
||||||
fn preserve_stub_apk(&self);
|
fn preserve_stub_apk(&self);
|
||||||
fn prune_su_access(&self);
|
fn prune_su_access(&self);
|
||||||
#[cxx_name = "get_manager"]
|
#[cxx_name = "get_manager"]
|
||||||
unsafe fn get_manager_for_cxx(&self, user: i32, ptr: *mut CxxString, install: bool) -> i32;
|
unsafe fn get_manager_for_cxx(&self, user: i32, ptr: *mut CxxString, install: bool) -> i32;
|
||||||
fn set_module_list(&self, module_list: Vec<ModuleInfo>);
|
fn set_module_list(&self, module_list: Vec<ModuleInfo>);
|
||||||
fn module_list(&self) -> &Vec<ModuleInfo>;
|
fn module_list(&self) -> &Vec<ModuleInfo>;
|
||||||
fn get_module_fds(&self, is_64_bit: bool) -> Vec<i32>;
|
|
||||||
|
|
||||||
#[cxx_name = "get_db_settings"]
|
#[cxx_name = "get_db_settings"]
|
||||||
fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool;
|
fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool;
|
||||||
@ -240,11 +242,9 @@ pub mod ffi {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn reboot(self: &MagiskD);
|
fn reboot(self: &MagiskD);
|
||||||
fn post_fs_data(self: &MagiskD) -> bool;
|
fn post_fs_data(self: &MagiskD) -> bool;
|
||||||
|
fn handle_modules(self: &MagiskD);
|
||||||
fn late_start(self: &MagiskD);
|
fn late_start(self: &MagiskD);
|
||||||
fn boot_complete(self: &MagiskD);
|
fn boot_complete(self: &MagiskD);
|
||||||
#[allow(dead_code)]
|
|
||||||
fn handle_modules(self: &MagiskD);
|
|
||||||
fn connect_zygiskd(self: &MagiskD, client: i32);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ static void inject_zygisk_libs(root_node *system) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_modules(const rust::Vec<ModuleInfo> &module_list) {
|
static void load_modules(bool zygisk_enabled, const rust::Vec<ModuleInfo> &module_list) {
|
||||||
node_entry::module_mnt = get_magisk_tmp() + "/"s MODULEMNT "/";
|
node_entry::module_mnt = get_magisk_tmp() + "/"s MODULEMNT "/";
|
||||||
|
|
||||||
auto root = make_unique<root_node>("");
|
auto root = make_unique<root_node>("");
|
||||||
@ -392,7 +392,7 @@ static void foreach_module(Func fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rust::Vec<ModuleInfo> collect_modules(bool open_zygisk) {
|
static rust::Vec<ModuleInfo> collect_modules(bool zygisk_enabled, bool open_zygisk) {
|
||||||
rust::Vec<ModuleInfo> modules;
|
rust::Vec<ModuleInfo> modules;
|
||||||
foreach_module([&](int dfd, dirent *entry, int modfd) {
|
foreach_module([&](int dfd, dirent *entry, int modfd) {
|
||||||
if (faccessat(modfd, "remove", F_OK, 0) == 0) {
|
if (faccessat(modfd, "remove", F_OK, 0) == 0) {
|
||||||
@ -475,11 +475,12 @@ static rust::Vec<ModuleInfo> collect_modules(bool open_zygisk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MagiskD::handle_modules() const noexcept {
|
void MagiskD::handle_modules() const noexcept {
|
||||||
|
bool zygisk = zygisk_enabled();
|
||||||
prepare_modules();
|
prepare_modules();
|
||||||
exec_module_scripts("post-fs-data", collect_modules(false));
|
exec_module_scripts("post-fs-data", collect_modules(zygisk, false));
|
||||||
// Recollect modules (module scripts could remove itself)
|
// Recollect modules (module scripts could remove itself)
|
||||||
auto list = collect_modules(true);
|
auto list = collect_modules(zygisk, true);
|
||||||
load_modules(list);
|
load_modules(zygisk, list);
|
||||||
set_module_list(std::move(list));
|
set_module_list(std::move(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ static void set_script_env() {
|
|||||||
char new_path[4096];
|
char new_path[4096];
|
||||||
ssprintf(new_path, sizeof(new_path), "%s:%s", getenv("PATH"), get_magisk_tmp());
|
ssprintf(new_path, sizeof(new_path), "%s:%s", getenv("PATH"), get_magisk_tmp());
|
||||||
setenv("PATH", new_path, 1);
|
setenv("PATH", new_path, 1);
|
||||||
if (zygisk_enabled)
|
if (MagiskD().zygisk_enabled())
|
||||||
setenv("ZYGISK_ENABLED", "1", 1);
|
setenv("ZYGISK_ENABLED", "1", 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
use crate::consts::MODULEROOT;
|
use crate::consts::MODULEROOT;
|
||||||
use crate::daemon::{to_user_id, IpcRead, MagiskD, UnixSocketExt};
|
use crate::daemon::{to_user_id, IpcRead, MagiskD, UnixSocketExt};
|
||||||
use crate::ffi::{update_deny_flags, ZygiskRequest, ZygiskStateFlags};
|
use crate::ffi::{
|
||||||
|
get_magisk_tmp, restore_zygisk_prop, update_deny_flags, ZygiskRequest, ZygiskStateFlags,
|
||||||
|
};
|
||||||
use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY};
|
use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY};
|
||||||
use base::{cstr, open_fd, Directory, FsPathBuf, LoggedResult, Utf8CStrBufArr, WriteExt};
|
use base::{
|
||||||
|
cstr, error, fork_dont_care, libc, open_fd, raw_cstr, warn, Directory, FsPathBuf, LoggedError,
|
||||||
|
LoggedResult, Utf8CStrBufArr, WriteExt,
|
||||||
|
};
|
||||||
|
use std::fmt::Write;
|
||||||
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
|
use std::ptr;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
const UNMOUNT_MASK: u32 =
|
const UNMOUNT_MASK: u32 =
|
||||||
ZygiskStateFlags::ProcessOnDenyList.repr | ZygiskStateFlags::DenyListEnforced.repr;
|
ZygiskStateFlags::ProcessOnDenyList.repr | ZygiskStateFlags::DenyListEnforced.repr;
|
||||||
@ -22,21 +30,119 @@ impl MagiskD {
|
|||||||
};
|
};
|
||||||
match code {
|
match code {
|
||||||
ZygiskRequest::GetInfo => self.get_process_info(client)?,
|
ZygiskRequest::GetInfo => self.get_process_info(client)?,
|
||||||
ZygiskRequest::ConnectCompanion => self.connect_zygiskd(client.as_raw_fd()),
|
ZygiskRequest::ConnectCompanion => self.connect_zygiskd(client),
|
||||||
ZygiskRequest::GetModDir => self.get_mod_dir(client)?,
|
ZygiskRequest::GetModDir => self.get_mod_dir(client)?,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_module_fds(&self, is_64_bit: bool) -> Vec<RawFd> {
|
pub fn zygisk_reset(&self, mut restore: bool) {
|
||||||
if let Some(module_list) = self.module_list.get() {
|
if !self.zygisk_enabled.load(Ordering::Acquire) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if restore {
|
||||||
|
self.zygote_start_count.store(1, Ordering::Release);
|
||||||
|
} else {
|
||||||
|
*self.zygiskd_sockets.lock().unwrap() = (None, None);
|
||||||
|
if self.zygote_start_count.fetch_add(1, Ordering::AcqRel) > 3 {
|
||||||
|
warn!("zygote crashes too many times, rolling-back");
|
||||||
|
restore = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if restore {
|
||||||
|
restore_zygisk_prop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_module_fds(&self, is_64_bit: bool) -> Option<Vec<RawFd>> {
|
||||||
|
self.module_list.get().map(|module_list| {
|
||||||
module_list
|
module_list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| if is_64_bit { m.z64 } else { m.z32 })
|
.map(|m| if is_64_bit { m.z64 } else { m.z32 })
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
})
|
||||||
Vec::new()
|
}
|
||||||
|
|
||||||
|
fn exec_zygiskd(is_64_bit: bool, remote: UnixStream) {
|
||||||
|
// This fd has to survive exec
|
||||||
|
unsafe {
|
||||||
|
libc::fcntl(remote.as_raw_fd(), libc::F_SETFD, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start building the exec arguments
|
||||||
|
let mut exe = Utf8CStrBufArr::<64>::new();
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
let magisk = if is_64_bit { "magisk" } else { "magisk32" };
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
let magisk = "magisk";
|
||||||
|
|
||||||
|
let exe = FsPathBuf::new(&mut exe).join(get_magisk_tmp()).join(magisk);
|
||||||
|
|
||||||
|
let mut fd_str = Utf8CStrBufArr::<16>::new();
|
||||||
|
write!(fd_str, "{}", remote.as_raw_fd()).ok();
|
||||||
|
unsafe {
|
||||||
|
libc::execl(
|
||||||
|
exe.as_ptr(),
|
||||||
|
raw_cstr!(""),
|
||||||
|
raw_cstr!("zygisk"),
|
||||||
|
raw_cstr!("companion"),
|
||||||
|
fd_str.as_ptr(),
|
||||||
|
ptr::null() as *const libc::c_char,
|
||||||
|
);
|
||||||
|
libc::exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect_zygiskd(&self, mut client: UnixStream) {
|
||||||
|
let mut zygiskd_sockets = self.zygiskd_sockets.lock().unwrap();
|
||||||
|
let result: LoggedResult<()> = try {
|
||||||
|
let is_64_bit = client.ipc_read_int()? != 0;
|
||||||
|
let socket = if is_64_bit {
|
||||||
|
&mut zygiskd_sockets.1
|
||||||
|
} else {
|
||||||
|
&mut zygiskd_sockets.0
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(fd) = socket {
|
||||||
|
// Make sure the socket is still valid
|
||||||
|
let mut pfd = libc::pollfd {
|
||||||
|
fd: fd.as_raw_fd(),
|
||||||
|
events: 0,
|
||||||
|
revents: 0,
|
||||||
|
};
|
||||||
|
if unsafe { libc::poll(&mut pfd, 1, 0) } != 0 || pfd.revents != 0 {
|
||||||
|
// Any revent means error
|
||||||
|
*socket = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let socket = if let Some(fd) = socket {
|
||||||
|
fd
|
||||||
|
} else {
|
||||||
|
// Create a new socket pair and fork zygiskd process
|
||||||
|
let (local, remote) = UnixStream::pair()?;
|
||||||
|
if fork_dont_care() == 0 {
|
||||||
|
Self::exec_zygiskd(is_64_bit, remote);
|
||||||
|
}
|
||||||
|
*socket = Some(local);
|
||||||
|
let local = socket.as_mut().unwrap();
|
||||||
|
if let Some(module_fds) = self.get_module_fds(is_64_bit) {
|
||||||
|
local.send_fds(&module_fds)?;
|
||||||
|
}
|
||||||
|
if local.ipc_read_int()? != 0 {
|
||||||
|
Err(LoggedError::default())?;
|
||||||
|
}
|
||||||
|
local
|
||||||
|
};
|
||||||
|
socket.send_fds(&[client.as_raw_fd()])?;
|
||||||
|
};
|
||||||
|
if result.is_err() {
|
||||||
|
error!("zygiskd startup error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,75 +30,10 @@ extern "C" [[maybe_unused]] NativeBridgeCallbacks NativeBridgeItf {
|
|||||||
|
|
||||||
// The following code runs in magiskd
|
// The following code runs in magiskd
|
||||||
|
|
||||||
static pthread_mutex_t zygiskd_lock = PTHREAD_MUTEX_INITIALIZER;
|
void restore_zygisk_prop() {
|
||||||
static int zygiskd_sockets[] = { -1, -1 };
|
string native_bridge_orig = "0";
|
||||||
#define zygiskd_socket zygiskd_sockets[is_64_bit]
|
if (native_bridge.length() > strlen(ZYGISKLDR)) {
|
||||||
|
native_bridge_orig = native_bridge.substr(strlen(ZYGISKLDR));
|
||||||
void MagiskD::connect_zygiskd(int client) const noexcept {
|
|
||||||
mutex_guard g(zygiskd_lock);
|
|
||||||
|
|
||||||
bool is_64_bit = read_int(client);
|
|
||||||
if (zygiskd_socket >= 0) {
|
|
||||||
// Make sure the socket is still valid
|
|
||||||
pollfd pfd = { zygiskd_socket, 0, 0 };
|
|
||||||
poll(&pfd, 1, 0);
|
|
||||||
if (pfd.revents) {
|
|
||||||
// Any revent means error
|
|
||||||
close(zygiskd_socket);
|
|
||||||
zygiskd_socket = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (zygiskd_socket < 0) {
|
|
||||||
int fds[2];
|
|
||||||
socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
|
|
||||||
zygiskd_socket = fds[0];
|
|
||||||
if (fork_dont_care() == 0) {
|
|
||||||
char exe[64];
|
|
||||||
#if defined(__LP64__)
|
|
||||||
ssprintf(exe, sizeof(exe), "%s/magisk%s", get_magisk_tmp(), (is_64_bit ? "" : "32"));
|
|
||||||
#else
|
|
||||||
ssprintf(exe, sizeof(exe), "%s/magisk", get_magisk_tmp());
|
|
||||||
#endif
|
|
||||||
// This fd has to survive exec
|
|
||||||
fcntl(fds[1], F_SETFD, 0);
|
|
||||||
char buf[16];
|
|
||||||
ssprintf(buf, sizeof(buf), "%d", fds[1]);
|
|
||||||
execl(exe, "", "zygisk", "companion", buf, (char *) nullptr);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
close(fds[1]);
|
|
||||||
rust::Vec<int> module_fds = get_module_fds(is_64_bit);
|
|
||||||
send_fds(zygiskd_socket, rust::Slice<const int>(module_fds));
|
|
||||||
// Wait for ack
|
|
||||||
if (read_int(zygiskd_socket) != 0) {
|
|
||||||
LOGE("zygiskd startup error\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
send_fd(zygiskd_socket, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_zygisk(bool restore) {
|
|
||||||
if (!zygisk_enabled) return;
|
|
||||||
static atomic_uint zygote_start_count{1};
|
|
||||||
if (!restore) {
|
|
||||||
close(zygiskd_sockets[0]);
|
|
||||||
close(zygiskd_sockets[1]);
|
|
||||||
zygiskd_sockets[0] = zygiskd_sockets[1] = -1;
|
|
||||||
}
|
|
||||||
if (restore) {
|
|
||||||
zygote_start_count = 1;
|
|
||||||
} else if (zygote_start_count.fetch_add(1) > 3) {
|
|
||||||
LOGW("zygote crashes too many times, rolling-back\n");
|
|
||||||
restore = true;
|
|
||||||
}
|
|
||||||
if (restore) {
|
|
||||||
string native_bridge_orig = "0";
|
|
||||||
if (native_bridge.length() > strlen(ZYGISKLDR)) {
|
|
||||||
native_bridge_orig = native_bridge.substr(strlen(ZYGISKLDR));
|
|
||||||
}
|
|
||||||
set_prop(NBPROP, native_bridge_orig.data());
|
|
||||||
} else {
|
|
||||||
set_prop(NBPROP, native_bridge.data());
|
|
||||||
}
|
}
|
||||||
|
set_prop(NBPROP, native_bridge_orig.data());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user