reformat code

This commit is contained in:
5ec1cff
2024-01-05 13:02:46 +08:00
parent 331b01b0f4
commit ad32c4efb0
10 changed files with 172 additions and 114 deletions

View File

@@ -107,7 +107,6 @@ androidComponents.onVariants { variant ->
.putLong(real.length())
.array()
sig.update(buffer)
println("sha $path ${real.length()}")
real.forEachBlock { bytes, size ->
sig.update(bytes, 0, size)
}

View File

@@ -1,13 +1,12 @@
use crate::dl;
use crate::utils::{check_unix_socket, UnixStreamExt};
use anyhow::Result;
use passfd::FdPassingExt;
use rustix::fs::fstat;
use std::ffi::c_void;
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
use std::os::unix::net::UnixStream;
use std::thread;
use anyhow::Result;
use passfd::FdPassingExt;
use rustix::fs::fstat;
use tokio::io::AsyncWriteExt;
use crate::utils::{check_unix_socket, UnixStreamExt};
use crate::dl;
type ZygiskCompanionEntryFn = unsafe extern "C" fn(i32);
@@ -28,7 +27,7 @@ pub fn entry(fd: i32) {
None => {
log::debug!("No companion entry for `{name}`");
stream.write_u8(0).expect("reply 0");
return ();
std::process::exit(0);
}
};
@@ -43,7 +42,9 @@ pub fn entry(fd: i32) {
stream.write_u8(1).expect("reply success");
thread::spawn(move || {
let st0 = fstat(&stream).expect("failed to stat stream");
unsafe { entry(stream.as_raw_fd()); }
unsafe {
entry(stream.as_raw_fd());
}
// Only close client if it is the same file so we don't
// accidentally close a re-used file descriptor.
// This check is required because the module companion

View File

@@ -1,32 +1,26 @@
use crate::lp_select;
use bitflags::bitflags;
use const_format::concatcp;
use konst::primitive::parse_i32;
use konst::unwrap_ctx;
use log::LevelFilter;
use num_enum::TryFromPrimitive;
use crate::lp_select;
pub const MIN_KSU_VERSION: i32 = unwrap_ctx!(parse_i32(env!("MIN_KSU_VERSION")));
pub const MAX_KSU_VERSION: i32 = unwrap_ctx!(parse_i32(env!("MAX_KSU_VERSION")));
pub const MIN_MAGISK_VERSION: i32 = unwrap_ctx!(parse_i32(env!("MIN_MAGISK_VERSION")));
pub const ZKSU_VERSION: &'static str = env!("ZKSU_VERSION");
pub const ZKSU_VERSION: &str = env!("ZKSU_VERSION");
#[cfg(debug_assertions)]
pub const MAX_LOG_LEVEL: LevelFilter = LevelFilter::Trace;
#[cfg(not(debug_assertions))]
pub const MAX_LOG_LEVEL: LevelFilter = LevelFilter::Info;
pub const PATH_MODULES_DIR: &str = "..";
pub const PATH_MODULE_PROP: &str = "module.prop";
pub const ZYGOTE_INJECTED: i32 = lp_select!(5, 4);
pub const DAEMON_SET_INFO: i32 = lp_select!(7, 6);
pub const DAEMON_SET_ERROR_INFO: i32 = lp_select!(9, 8);
pub const SYSTEM_SERVER_STARTED: i32 = 10;
pub const MAX_RESTART_COUNT: i32 = 5;
#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum DaemonSocketAction {

View File

@@ -30,13 +30,13 @@ extern "C" {
}
type AndroidCreateNamespaceFn = unsafe extern "C" fn(
*const c_char, // name
*const c_char, // ld_library_path
*const c_char, // default_library_path
u64, // type
*const c_char, // permitted_when_isolated_path
*mut AndroidNamespace, // parent
*const c_void, // caller_addr
*const c_char, // name
*const c_char, // ld_library_path
*const c_char, // default_library_path
u64, // type
*const c_char, // permitted_when_isolated_path
*mut AndroidNamespace, // parent
*const c_void, // caller_addr
) -> *mut AndroidNamespace;
pub unsafe fn dlopen(path: &str, flags: i32) -> Result<*mut c_void> {
@@ -57,11 +57,15 @@ pub unsafe fn dlopen(path: &str, flags: i32) -> Result<*mut c_void> {
libc::RTLD_DEFAULT,
std::ffi::CString::new("__loader_android_create_namespace")?.as_ptr(),
);
let android_create_namespace_fn: AndroidCreateNamespaceFn = std::mem::transmute(android_create_namespace_fn);
let android_create_namespace_fn: AndroidCreateNamespaceFn =
std::mem::transmute(android_create_namespace_fn);
let ns = android_create_namespace_fn(
filename, dir, std::ptr::null(),
filename,
dir,
std::ptr::null(),
ANDROID_NAMESPACE_TYPE_SHARED,
std::ptr::null(), std::ptr::null_mut(),
std::ptr::null(),
std::ptr::null_mut(),
&dlopen as *const _ as *const c_void,
);
if ns != std::ptr::null_mut() {

View File

@@ -1,11 +1,10 @@
mod companion;
mod constants;
mod dl;
mod root_impl;
mod utils;
mod zygiskd;
mod companion;
use std::future::Future;
use crate::constants::ZKSU_VERSION;
fn init_android_logger(tag: &str) {

View File

@@ -71,7 +71,7 @@ pub fn uid_should_umount(uid: i32) -> bool {
// TODO: signature
pub fn uid_is_manager(uid: i32) -> bool {
if let Ok(s) = rustix::fs::stat("/data/user_de/0/me.weishu.kernelsu") {
return s.st_uid == uid as u32
return s.st_uid == uid as u32;
}
false
}

View File

@@ -1,5 +1,5 @@
use std::process::{Command, Stdio};
use crate::constants::MIN_MAGISK_VERSION;
use std::process::{Command, Stdio};
const MAGISK_VANILLA: &str = "com.topjohnwu.magisk";
const MAGISK_ALPHA: &str = "io.github.vvb2060.magisk";
@@ -15,21 +15,25 @@ pub fn get_magisk() -> Option<Version> {
Command::new("magisk")
.arg("-v")
.stdout(Stdio::piped())
.spawn().ok()
.spawn()
.ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|version| {
if (version.contains("alpha")) {
if version.contains("alpha") {
MAGISK_ALPHA
} else {
MAGISK_VANILLA
}
})
.map(|variant| { unsafe { VARIANT = variant }; });
.map(|variant| {
unsafe { VARIANT = variant };
});
let version: Option<i32> = Command::new("magisk")
.arg("-V")
.stdout(Stdio::piped())
.spawn().ok()
.spawn()
.ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok())
.and_then(|output| output.trim().parse().ok());
@@ -45,19 +49,24 @@ pub fn get_magisk() -> Option<Version> {
pub fn uid_granted_root(uid: i32) -> bool {
Command::new("magisk")
.arg("--sqlite")
.arg(format!("select 1 from policies where uid={uid} and policy=2 limit 1"))
.arg(format!(
"select 1 from policies where uid={uid} and policy=2 limit 1"
))
.stdout(Stdio::piped())
.spawn().ok()
.spawn()
.ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|output| output.is_empty()) == Some(false)
.map(|output| output.is_empty())
== Some(false)
}
pub fn uid_should_umount(uid: i32) -> bool {
let output = Command::new("pm")
.args(["list", "packages", "--uid", &uid.to_string()])
.stdout(Stdio::piped())
.spawn().ok()
.spawn()
.ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok());
let line = match output {
@@ -73,12 +82,16 @@ pub fn uid_should_umount(uid: i32) -> bool {
};
Command::new("magisk")
.arg("--sqlite")
.arg(format!("select 1 from denylist where package_name=\"{pkg}\" limit 1"))
.arg(format!(
"select 1 from denylist where package_name=\"{pkg}\" limit 1"
))
.stdout(Stdio::piped())
.spawn().ok()
.spawn()
.ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|output| output.is_empty()) == Some(false)
.map(|output| output.is_empty())
== Some(false)
}
// TODO: signature
@@ -86,9 +99,12 @@ pub fn uid_should_umount(uid: i32) -> bool {
pub fn uid_is_manager(uid: i32) -> bool {
let output = Command::new("magisk")
.arg("--sqlite")
.arg(format!("select value from strings where key=\"requester\" limit 1"))
.arg(format!(
"select value from strings where key=\"requester\" limit 1"
))
.stdout(Stdio::piped())
.spawn().ok()
.spawn()
.ok()
.and_then(|child| child.wait_with_output().ok())
.and_then(|output| String::from_utf8(output.stdout).ok())
.map(|output| output.trim().to_string());

View File

@@ -20,21 +20,19 @@ pub fn setup() {
let impl_ = match (ksu_version, magisk_version) {
(None, None) => RootImpl::None,
(Some(_), Some(_)) => RootImpl::Multiple,
(Some(ksu_version), None) => {
match ksu_version {
kernelsu::Version::Supported => RootImpl::KernelSU,
kernelsu::Version::TooOld => RootImpl::TooOld,
kernelsu::Version::Abnormal => RootImpl::Abnormal,
}
}
(None, Some(magisk_version)) => {
match magisk_version {
magisk::Version::Supported => RootImpl::Magisk,
magisk::Version::TooOld => RootImpl::TooOld,
}
}
(Some(ksu_version), None) => match ksu_version {
kernelsu::Version::Supported => RootImpl::KernelSU,
kernelsu::Version::TooOld => RootImpl::TooOld,
kernelsu::Version::Abnormal => RootImpl::Abnormal,
},
(None, Some(magisk_version)) => match magisk_version {
magisk::Version::Supported => RootImpl::Magisk,
magisk::Version::TooOld => RootImpl::TooOld,
},
};
unsafe { ROOT_IMPL = impl_; }
unsafe {
ROOT_IMPL = impl_;
}
}
pub fn get_impl() -> &'static RootImpl {

View File

@@ -1,35 +1,49 @@
use anyhow::Result;
use std::{fs, io::{Read, Write}, os::unix::net::UnixStream};
use std::ffi::{c_char, c_void, CStr, CString};
use std::os::fd::{AsFd, AsRawFd};
use std::os::unix::net::{UnixDatagram, UnixListener};
use std::process::Command;
use std::sync::OnceLock;
use bitflags::Flags;
use rustix::net::{AddressFamily, bind_unix, connect_unix, listen, SendFlags, sendto_unix, socket, SocketAddrUnix, SocketType};
use rustix::net::{
bind_unix, connect_unix, listen, sendto_unix, socket, AddressFamily, SendFlags, SocketAddrUnix,
SocketType,
};
use rustix::path::Arg;
use rustix::thread::gettid;
use std::ffi::{c_char, c_void, CStr, CString};
use std::os::fd::{AsFd, AsRawFd};
use std::os::unix::net::{UnixListener};
use std::process::Command;
use std::sync::OnceLock;
use std::{
fs,
io::{Read, Write},
os::unix::net::UnixStream,
};
#[cfg(target_pointer_width = "64")]
#[macro_export]
macro_rules! lp_select {
($lp32:expr, $lp64:expr) => { $lp64 };
($lp32:expr, $lp64:expr) => {
$lp64
};
}
#[cfg(target_pointer_width = "32")]
#[macro_export]
macro_rules! lp_select {
($lp32:expr, $lp64:expr) => { $lp32 };
($lp32:expr, $lp64:expr) => {
$lp32
};
}
#[cfg(debug_assertions)]
#[macro_export]
macro_rules! debug_select {
($debug:expr, $release:expr) => { $debug };
($debug:expr, $release:expr) => {
$debug
};
}
#[cfg(not(debug_assertions))]
#[macro_export]
macro_rules! debug_select {
($debug:expr, $release:expr) => { $release };
($debug:expr, $release:expr) => {
$release
};
}
pub struct LateInit<T> {
@@ -38,7 +52,9 @@ pub struct LateInit<T> {
impl<T> LateInit<T> {
pub const fn new() -> Self {
LateInit { cell: OnceLock::new() }
LateInit {
cell: OnceLock::new(),
}
}
pub fn init(&self, value: T) {
@@ -58,7 +74,10 @@ pub fn set_socket_create_context(context: &str) -> Result<()> {
match fs::write(path, context) {
Ok(_) => Ok(()),
Err(_) => {
let path = format!("/proc/self/task/{}/attr/sockcreate", gettid().as_raw_nonzero());
let path = format!(
"/proc/self/task/{}/attr/sockcreate",
gettid().as_raw_nonzero()
);
fs::write(path, context)?;
Ok(())
}
@@ -94,6 +113,7 @@ pub fn get_property(name: &str) -> Result<String> {
Ok(prop.to_string_lossy().to_string())
}
#[allow(dead_code)]
pub fn set_property(name: &str, value: &str) -> Result<()> {
let name = CString::new(name)?;
let value = CString::new(value)?;
@@ -103,11 +123,10 @@ pub fn set_property(name: &str, value: &str) -> Result<()> {
Ok(())
}
#[allow(dead_code)]
pub fn wait_property(name: &str, serial: u32) -> Result<u32> {
let name = CString::new(name)?;
let info = unsafe {
__system_property_find(name.as_ptr())
};
let info = unsafe { __system_property_find(name.as_ptr()) };
let mut serial = serial;
unsafe {
__system_property_wait(info, serial, &mut serial, std::ptr::null());
@@ -115,14 +134,11 @@ pub fn wait_property(name: &str, serial: u32) -> Result<u32> {
Ok(serial)
}
#[allow(dead_code)]
pub fn get_property_serial(name: &str) -> Result<u32> {
let name = CString::new(name)?;
let info = unsafe {
__system_property_find(name.as_ptr())
};
Ok(unsafe {
__system_property_serial(info)
})
let info = unsafe { __system_property_find(name.as_ptr()) };
Ok(unsafe { __system_property_serial(info) })
}
pub fn switch_mount_namespace(pid: i32) -> Result<()> {
@@ -234,6 +250,11 @@ extern "C" {
fn __system_property_get(name: *const c_char, value: *mut c_char) -> u32;
fn __system_property_set(name: *const c_char, value: *const c_char) -> u32;
fn __system_property_find(name: *const c_char) -> *const c_void;
fn __system_property_wait(info: *const c_void, old_serial: u32, new_serial: *mut u32, timeout: *const libc::timespec) -> bool;
fn __system_property_wait(
info: *const c_void,
old_serial: u32,
new_serial: *mut u32,
timeout: *const libc::timespec,
) -> bool;
fn __system_property_serial(info: *const c_void) -> u32;
}

View File

@@ -2,23 +2,22 @@ use crate::constants::{DaemonSocketAction, ProcessFlags};
use crate::utils::{check_unix_socket, LateInit, UnixStreamExt};
use crate::{constants, lp_select, root_impl, utils};
use anyhow::{bail, Result};
use log::{debug, error, info, trace, warn};
use passfd::FdPassingExt;
use std::sync::{Arc, Mutex};
use std::thread;
use rustix::fs::{fcntl_setfd, FdFlags};
use std::fs;
use std::io::Error;
use std::ops::Deref;
use std::os::fd::{AsFd, OwnedFd, RawFd};
use std::os::unix::process::CommandExt;
use std::os::unix::{
net::{UnixListener, UnixStream},
prelude::AsRawFd,
};
use std::path::PathBuf;
use std::process::{Command, exit};
use log::{debug, error, info, trace, warn};
use std::os::unix::process::CommandExt;
use bitflags::Flags;
use rustix::fs::{fcntl_setfd, FdFlags};
use std::process::{exit, Command};
use std::sync::{Arc, Mutex};
use std::thread;
struct Module {
name: String,
@@ -39,7 +38,11 @@ pub fn main() -> Result<()> {
TMP_PATH.init(std::env::var("TMP_PATH")?);
CONTROLLER_SOCKET.init(format!("{}/init_monitor", TMP_PATH.deref()));
PATH_CP_NAME.init(format!("{}/{}", TMP_PATH.deref(), lp_select!("/cp32.sock", "/cp64.sock")));
PATH_CP_NAME.init(format!(
"{}/{}",
TMP_PATH.deref(),
lp_select!("/cp32.sock", "/cp64.sock")
));
let arch = get_arch()?;
debug!("Daemon architecture: {arch}");
@@ -50,9 +53,13 @@ pub fn main() -> Result<()> {
let info = match root_impl::get_impl() {
root_impl::RootImpl::KernelSU | root_impl::RootImpl::Magisk => {
msg.extend_from_slice(&constants::DAEMON_SET_INFO.to_le_bytes());
let module_names: Vec<_> = modules.iter()
.map(|m| m.name.as_str()).collect();
format!("Root: {:?},module({}): {}", root_impl::get_impl(), modules.len(), module_names.join(","))
let module_names: Vec<_> = modules.iter().map(|m| m.name.as_str()).collect();
format!(
"Root: {:?},module({}): {}",
root_impl::get_impl(),
modules.len(),
module_names.join(",")
)
}
_ => {
msg.extend_from_slice(&constants::DAEMON_SET_ERROR_INFO.to_le_bytes());
@@ -62,12 +69,11 @@ pub fn main() -> Result<()> {
msg.extend_from_slice(&(info.len() as u32 + 1).to_le_bytes());
msg.extend_from_slice(info.as_bytes());
msg.extend_from_slice(&[0u8]);
utils::unix_datagram_sendto(&CONTROLLER_SOCKET, msg.as_slice()).expect("failed to send info");
utils::unix_datagram_sendto(&CONTROLLER_SOCKET, msg.as_slice())
.expect("failed to send info");
}
let context = Context {
modules,
};
let context = Context { modules };
let context = Arc::new(context);
let listener = create_daemon_socket()?;
for stream in listener.incoming() {
@@ -142,7 +148,11 @@ fn load_modules(arch: &str) -> Result<Vec<Module>> {
}
};
let companion = Mutex::new(None);
let module = Module { name, lib_fd, companion };
let module = Module {
name,
lib_fd,
companion,
};
modules.push(module);
}
@@ -213,19 +223,21 @@ fn spawn_companion(name: &str, lib_fd: RawFd) -> Result<Option<UnixStream>> {
exit(0)
}
fn handle_daemon_action(action: DaemonSocketAction, mut stream: UnixStream, context: &Context) -> Result<()> {
fn handle_daemon_action(
action: DaemonSocketAction,
mut stream: UnixStream,
context: &Context,
) -> Result<()> {
match action {
DaemonSocketAction::RequestLogcatFd => {
loop {
let level = match stream.read_u8() {
Ok(level) => level,
Err(_) => break,
};
let tag = stream.read_string()?;
let message = stream.read_string()?;
utils::log_raw(level as i32, &tag, &message)?;
}
}
DaemonSocketAction::RequestLogcatFd => loop {
let level = match stream.read_u8() {
Ok(level) => level,
Err(_) => break,
};
let tag = stream.read_string()?;
let message = stream.read_string()?;
utils::log_raw(level as i32, &tag, &message)?;
},
DaemonSocketAction::GetProcessFlags => {
let uid = stream.read_u32()? as i32;
let mut flags = ProcessFlags::empty();
@@ -244,8 +256,16 @@ fn handle_daemon_action(action: DaemonSocketAction, mut stream: UnixStream, cont
root_impl::RootImpl::Magisk => flags |= ProcessFlags::PROCESS_ROOT_IS_MAGISK,
_ => panic!("wrong root impl: {:?}", root_impl::get_impl()),
}
trace!("Uid {} granted root: {}", uid, flags.contains(ProcessFlags::PROCESS_GRANTED_ROOT));
trace!("Uid {} on denylist: {}", uid, flags.contains(ProcessFlags::PROCESS_ON_DENYLIST));
trace!(
"Uid {} granted root: {}",
uid,
flags.contains(ProcessFlags::PROCESS_GRANTED_ROOT)
);
trace!(
"Uid {} on denylist: {}",
uid,
flags.contains(ProcessFlags::PROCESS_ON_DENYLIST)
);
stream.write_u32(flags.bits())?;
}
DaemonSocketAction::ReadModules => {
@@ -271,7 +291,10 @@ fn handle_daemon_action(action: DaemonSocketAction, mut stream: UnixStream, cont
if c.is_some() {
trace!(" Spawned companion for `{}`", module.name);
} else {
trace!(" No companion spawned for `{}` because it has not entry", module.name);
trace!(
" No companion spawned for `{}` because it has not entry",
module.name
);
}
*companion = Some(c);
}
@@ -283,7 +306,10 @@ fn handle_daemon_action(action: DaemonSocketAction, mut stream: UnixStream, cont
match companion.as_ref() {
Some(Some(sock)) => {
if let Err(e) = sock.send_fd(stream.as_raw_fd()) {
error!("Failed to send companion fd socket of module `{}`: {}", module.name, e);
error!(
"Failed to send companion fd socket of module `{}`: {}",
module.name, e
);
stream.write_u8(0)?;
}
// Ok: Send by companion