mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-27 15:20:58 +00:00
Migrate setup_magisk_env to Rust
This commit is contained in:
@@ -18,7 +18,6 @@ use std::fmt::Display;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write};
|
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::os::fd::{AsFd, BorrowedFd};
|
use std::os::fd::{AsFd, BorrowedFd};
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::os::unix::io::{AsRawFd, OwnedFd, RawFd};
|
use std::os::unix::io::{AsRawFd, OwnedFd, RawFd};
|
||||||
@@ -307,17 +306,12 @@ impl Utf8CStr {
|
|||||||
|
|
||||||
pub fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> {
|
pub fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> {
|
||||||
if !attr.is_symlink()
|
if !attr.is_symlink()
|
||||||
&& let Err(e) = nix::sys::stat::fchmodat(
|
&& let Err(e) = self.follow_link().chmod((attr.st.st_mode & 0o777).as_())
|
||||||
AT_FDCWD,
|
|
||||||
self,
|
|
||||||
Mode::from_bits_truncate((attr.st.st_mode & 0o777).as_()),
|
|
||||||
FchmodatFlags::FollowSymlink,
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// Double check if self is symlink before reporting error
|
// Double check if self is symlink before reporting error
|
||||||
let self_attr = self.get_attr()?;
|
let self_attr = self.get_attr()?;
|
||||||
if !self_attr.is_symlink() {
|
if !self_attr.is_symlink() {
|
||||||
return Err(OsError::new(e, "chmod", Some(self), None));
|
return Err(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,13 +515,27 @@ impl Utf8CStr {
|
|||||||
|
|
||||||
impl FsPathFollow {
|
impl FsPathFollow {
|
||||||
pub fn exists(&self) -> bool {
|
pub fn exists(&self) -> bool {
|
||||||
nix::unistd::access(self.deref(), AccessFlags::F_OK).is_ok()
|
nix::unistd::access(self.as_utf8_cstr(), AccessFlags::F_OK).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chmod(&self, mode: mode_t) -> OsResult<'_, ()> {
|
||||||
|
nix::sys::stat::fchmodat(
|
||||||
|
AT_FDCWD,
|
||||||
|
self.as_utf8_cstr(),
|
||||||
|
Mode::from_bits_truncate(mode),
|
||||||
|
FchmodatFlags::FollowSymlink,
|
||||||
|
)
|
||||||
|
.check_os_err("chmod", Some(self), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_attr(&self) -> OsResult<'_, FileAttr> {
|
pub fn get_attr(&self) -> OsResult<'_, FileAttr> {
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut attr = FileAttr {
|
let mut attr = FileAttr {
|
||||||
st: nix::sys::stat::stat(self.deref()).into_os_result("lstat", Some(self), None)?,
|
st: nix::sys::stat::stat(self.as_utf8_cstr()).into_os_result(
|
||||||
|
"lstat",
|
||||||
|
Some(self),
|
||||||
|
None,
|
||||||
|
)?,
|
||||||
#[cfg(feature = "selinux")]
|
#[cfg(feature = "selinux")]
|
||||||
con: cstr::buf::new(),
|
con: cstr::buf::new(),
|
||||||
};
|
};
|
||||||
@@ -537,16 +545,10 @@ impl FsPathFollow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> {
|
pub fn set_attr<'a>(&'a self, attr: &'a FileAttr) -> OsResult<'a, ()> {
|
||||||
nix::sys::stat::fchmodat(
|
self.chmod((attr.st.st_mode & 0o777).as_())?;
|
||||||
AT_FDCWD,
|
|
||||||
self.deref(),
|
|
||||||
Mode::from_bits_truncate((attr.st.st_mode & 0o777).as_()),
|
|
||||||
FchmodatFlags::FollowSymlink,
|
|
||||||
)
|
|
||||||
.check_os_err("chmod", Some(self), None)?;
|
|
||||||
|
|
||||||
nix::unistd::chown(
|
nix::unistd::chown(
|
||||||
self.deref(),
|
self.as_utf8_cstr(),
|
||||||
Some(Uid::from(attr.st.st_uid)),
|
Some(Uid::from(attr.st.st_uid)),
|
||||||
Some(Gid::from(attr.st.st_gid)),
|
Some(Gid::from(attr.st.st_gid)),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -214,53 +214,6 @@ int connect_daemon(int req, bool create) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setup_magisk_env() {
|
|
||||||
char buf[4096];
|
|
||||||
|
|
||||||
LOGI("* Initializing Magisk environment\n");
|
|
||||||
|
|
||||||
ssprintf(buf, sizeof(buf), "%s/0/%s/install", APP_DATA_DIR, JAVA_PACKAGE_NAME);
|
|
||||||
// Alternative binaries paths
|
|
||||||
const char *alt_bin[] = { "/cache/data_adb/magisk", "/data/magisk", buf };
|
|
||||||
for (auto alt : alt_bin) {
|
|
||||||
if (access(alt, F_OK) == 0) {
|
|
||||||
rm_rf(DATABIN);
|
|
||||||
cp_afc(alt, DATABIN);
|
|
||||||
rm_rf(alt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rm_rf("/cache/data_adb");
|
|
||||||
|
|
||||||
// Directories in /data/adb
|
|
||||||
chmod(SECURE_DIR, 0700);
|
|
||||||
xmkdir(DATABIN, 0755);
|
|
||||||
xmkdir(MODULEROOT, 0755);
|
|
||||||
xmkdir(SECURE_DIR "/post-fs-data.d", 0755);
|
|
||||||
xmkdir(SECURE_DIR "/service.d", 0755);
|
|
||||||
restorecon();
|
|
||||||
|
|
||||||
if (access(DATABIN "/busybox", X_OK))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ssprintf(buf, sizeof(buf), "%s/" BBPATH "/busybox", get_magisk_tmp());
|
|
||||||
mkdir(dirname(buf), 0755);
|
|
||||||
cp_afc(DATABIN "/busybox", buf);
|
|
||||||
exec_command_async(buf, "--install", "-s", dirname(buf));
|
|
||||||
|
|
||||||
// magisk32 and magiskpolicy are not installed into ramdisk and has to be copied
|
|
||||||
// from data to magisk tmp
|
|
||||||
if (access(DATABIN "/magisk32", X_OK) == 0) {
|
|
||||||
ssprintf(buf, sizeof(buf), "%s/magisk32", get_magisk_tmp());
|
|
||||||
cp_afc(DATABIN "/magisk32", buf);
|
|
||||||
}
|
|
||||||
if (access(DATABIN "/magiskpolicy", X_OK) == 0) {
|
|
||||||
ssprintf(buf, sizeof(buf), "%s/magiskpolicy", get_magisk_tmp());
|
|
||||||
cp_afc(DATABIN "/magiskpolicy", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock_blocks() {
|
void unlock_blocks() {
|
||||||
int fd, dev, OFF = 0;
|
int fd, dev, OFF = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use crate::UCred;
|
use crate::UCred;
|
||||||
use crate::consts::{
|
use crate::consts::{
|
||||||
MAGISK_FULL_VER, MAGISK_PROC_CON, MAGISK_VER_CODE, MAGISK_VERSION, MAIN_CONFIG, ROOTMNT,
|
APP_PACKAGE_NAME, BBPATH, DATABIN, MAGISK_FULL_VER, MAGISK_PROC_CON, MAGISK_VER_CODE,
|
||||||
ROOTOVL, SECURE_DIR,
|
MAGISK_VERSION, MAIN_CONFIG, MODULEROOT, ROOTMNT, ROOTOVL, SECURE_DIR,
|
||||||
};
|
};
|
||||||
use crate::db::Sqlite3;
|
use crate::db::Sqlite3;
|
||||||
use crate::ffi::{
|
use crate::ffi::{
|
||||||
DbEntryKey, ModuleInfo, RequestCode, check_key_combo, denylist_handler, exec_common_scripts,
|
DbEntryKey, ModuleInfo, RequestCode, check_key_combo, denylist_handler, exec_common_scripts,
|
||||||
exec_module_scripts, get_magisk_tmp, initialize_denylist, scan_deny_apps, setup_magisk_env,
|
exec_module_scripts, get_magisk_tmp, initialize_denylist, scan_deny_apps,
|
||||||
};
|
};
|
||||||
use crate::logging::{android_logging, magisk_logging, setup_logfile, start_log_daemon};
|
use crate::logging::{android_logging, magisk_logging, setup_logfile, start_log_daemon};
|
||||||
use crate::module::{disable_modules, remove_modules};
|
use crate::module::{disable_modules, remove_modules};
|
||||||
use crate::mount::{clean_mounts, setup_preinit_dir};
|
use crate::mount::{clean_mounts, setup_preinit_dir};
|
||||||
use crate::package::ManagerInfo;
|
use crate::package::ManagerInfo;
|
||||||
use crate::resetprop::{get_prop, set_prop};
|
use crate::resetprop::{get_prop, set_prop};
|
||||||
use crate::selinux::restore_tmpcon;
|
use crate::selinux::{restore_tmpcon, restorecon};
|
||||||
use crate::socket::IpcWrite;
|
use crate::socket::IpcWrite;
|
||||||
use crate::su::SuInfo;
|
use crate::su::SuInfo;
|
||||||
use crate::zygisk::ZygiskState;
|
use crate::zygisk::ZygiskState;
|
||||||
@@ -32,7 +32,7 @@ use std::fmt::Write as FmtWrite;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Write};
|
use std::io::{BufReader, Write};
|
||||||
use std::os::fd::{AsFd, FromRawFd, IntoRawFd, OwnedFd};
|
use std::os::fd::{AsFd, FromRawFd, IntoRawFd, OwnedFd};
|
||||||
use std::process::{Command, exit};
|
use std::process::{Command, Stdio, exit};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Mutex, OnceLock};
|
use std::sync::{Mutex, OnceLock};
|
||||||
|
|
||||||
@@ -106,6 +106,83 @@ impl MagiskD {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup_magisk_env(&self) -> bool {
|
||||||
|
info!("* Initializing Magisk environment");
|
||||||
|
|
||||||
|
let mut buf = cstr::buf::default();
|
||||||
|
|
||||||
|
let app_bin_dir = buf
|
||||||
|
.append_path(self.app_data_dir())
|
||||||
|
.append_path("0")
|
||||||
|
.append_path(APP_PACKAGE_NAME)
|
||||||
|
.append_path("install");
|
||||||
|
|
||||||
|
// Alternative binaries paths
|
||||||
|
let alt_bin_dirs = &[
|
||||||
|
cstr!("/cache/data_adb/magisk"),
|
||||||
|
cstr!("/data/magisk"),
|
||||||
|
app_bin_dir,
|
||||||
|
];
|
||||||
|
for dir in alt_bin_dirs {
|
||||||
|
if dir.exists() {
|
||||||
|
cstr!(DATABIN).remove_all().ok();
|
||||||
|
dir.copy_to(cstr!(DATABIN)).ok();
|
||||||
|
dir.remove_all().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cstr!("/cache/data_adb").remove_all().ok();
|
||||||
|
|
||||||
|
// Directories in /data/adb
|
||||||
|
cstr!(SECURE_DIR).follow_link().chmod(0o700).log_ok();
|
||||||
|
cstr!(DATABIN).mkdir(0o755).log_ok();
|
||||||
|
cstr!(MODULEROOT).mkdir(0o755).log_ok();
|
||||||
|
cstr!(concatcp!(SECURE_DIR, "/post-fs-data.d"))
|
||||||
|
.mkdir(0o755)
|
||||||
|
.log_ok();
|
||||||
|
cstr!(concatcp!(SECURE_DIR, "/service.d"))
|
||||||
|
.mkdir(0o755)
|
||||||
|
.log_ok();
|
||||||
|
restorecon();
|
||||||
|
|
||||||
|
let busybox = cstr!(concatcp!(DATABIN, "/busybox"));
|
||||||
|
if !busybox.exists() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tmp_bb = buf.append_path(get_magisk_tmp()).append_path(BBPATH);
|
||||||
|
tmp_bb.mkdirs(0o755).ok();
|
||||||
|
tmp_bb.append_path("busybox");
|
||||||
|
tmp_bb.follow_link().chmod(0o755).log_ok();
|
||||||
|
busybox.copy_to(tmp_bb).ok();
|
||||||
|
|
||||||
|
// Install busybox applets
|
||||||
|
Command::new(&tmp_bb)
|
||||||
|
.arg("--install")
|
||||||
|
.arg("-s")
|
||||||
|
.arg(tmp_bb.parent_dir().unwrap())
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.status()
|
||||||
|
.log_ok();
|
||||||
|
|
||||||
|
// magisk32 and magiskpolicy are not installed into ramdisk and has to be copied
|
||||||
|
// from data to magisk tmp
|
||||||
|
let magisk32 = cstr!(concatcp!(DATABIN, "/magisk32"));
|
||||||
|
if magisk32.exists() {
|
||||||
|
let tmp = buf.append_path(get_magisk_tmp()).append_path("magisk32");
|
||||||
|
magisk32.copy_to(tmp).log_ok();
|
||||||
|
}
|
||||||
|
let magiskpolicy = cstr!(concatcp!(DATABIN, "/magiskpolicy"));
|
||||||
|
if magiskpolicy.exists() {
|
||||||
|
let tmp = buf
|
||||||
|
.append_path(get_magisk_tmp())
|
||||||
|
.append_path("magiskpolicy");
|
||||||
|
magiskpolicy.copy_to(tmp).log_ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn post_fs_data(&self) -> bool {
|
fn post_fs_data(&self) -> bool {
|
||||||
setup_logfile();
|
setup_logfile();
|
||||||
info!("** post-fs-data mode running");
|
info!("** post-fs-data mode running");
|
||||||
@@ -125,7 +202,7 @@ impl MagiskD {
|
|||||||
|
|
||||||
self.prune_su_access();
|
self.prune_su_access();
|
||||||
|
|
||||||
if !setup_magisk_env() {
|
if !self.setup_magisk_env() {
|
||||||
error!("* Magisk environment incomplete, abort");
|
error!("* Magisk environment incomplete, abort");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ struct ModuleInfo;
|
|||||||
int connect_daemon(int req, bool create = false);
|
int connect_daemon(int req, bool create = false);
|
||||||
const char *get_magisk_tmp();
|
const char *get_magisk_tmp();
|
||||||
void unlock_blocks();
|
void unlock_blocks();
|
||||||
bool setup_magisk_env();
|
|
||||||
bool check_key_combo();
|
bool check_key_combo();
|
||||||
|
|
||||||
template<typename T> requires(std::is_trivially_copyable_v<T>)
|
template<typename T> requires(std::is_trivially_copyable_v<T>)
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ pub mod ffi {
|
|||||||
fn get_magisk_tmp() -> Utf8CStrRef<'static>;
|
fn get_magisk_tmp() -> Utf8CStrRef<'static>;
|
||||||
#[cxx_name = "resolve_preinit_dir_rs"]
|
#[cxx_name = "resolve_preinit_dir_rs"]
|
||||||
fn resolve_preinit_dir(base_dir: Utf8CStrRef) -> String;
|
fn resolve_preinit_dir(base_dir: Utf8CStrRef) -> String;
|
||||||
fn setup_magisk_env() -> bool;
|
|
||||||
fn check_key_combo() -> bool;
|
fn check_key_combo() -> bool;
|
||||||
#[cxx_name = "exec_script_rs"]
|
#[cxx_name = "exec_script_rs"]
|
||||||
fn exec_script(script: Utf8CStrRef);
|
fn exec_script(script: Utf8CStrRef);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ pub const MAIN_CONFIG: &str = concatcp!(INTERNAL_DIR, "/config");
|
|||||||
pub const PREINITMIRR: &str = concatcp!(INTERNAL_DIR, "/preinit");
|
pub const PREINITMIRR: &str = concatcp!(INTERNAL_DIR, "/preinit");
|
||||||
pub const MODULEMNT: &str = concatcp!(INTERNAL_DIR, "/modules");
|
pub const MODULEMNT: &str = concatcp!(INTERNAL_DIR, "/modules");
|
||||||
pub const WORKERDIR: &str = concatcp!(INTERNAL_DIR, "/worker");
|
pub const WORKERDIR: &str = concatcp!(INTERNAL_DIR, "/worker");
|
||||||
|
pub const BBPATH: &str = concatcp!(INTERNAL_DIR, "/busybox");
|
||||||
pub const DEVICEDIR: &str = concatcp!(INTERNAL_DIR, "/device");
|
pub const DEVICEDIR: &str = concatcp!(INTERNAL_DIR, "/device");
|
||||||
pub const PREINITDEV: &str = concatcp!(DEVICEDIR, "/preinit");
|
pub const PREINITDEV: &str = concatcp!(DEVICEDIR, "/preinit");
|
||||||
pub const LOG_PIPE: &str = concatcp!(DEVICEDIR, "/log");
|
pub const LOG_PIPE: &str = concatcp!(DEVICEDIR, "/log");
|
||||||
|
|||||||
Reference in New Issue
Block a user