ksud: Optimise ksud (#576)
* opt: Optimize printing for result isn't successful - print chain && backtrace to stderr Signed-off-by: Tools-app <localhost.hutao@gmail.com> * ci(ksud): add CARGO_TERM_COLOR for build Signed-off-by: Tools-app <localhost.hutao@gmail.com> * fix(ksud): fix uninstall package name is `me.weishu.kernelsu` Signed-off-by: Tools-app <localhost.hutao@gmail.com> * fix(ksud): Reverted to a private function for get_kernel_version Signed-off-by: Tools-app <localhost.hutao@gmail.com> * chore: format code for magic_mount.rs Signed-off-by: Tools-app <localhost.hutao@gmail.com> * fix: fix rustfmt Signed-off-by: Tools-app <localhost.hutao@gmail.com> * feat: Move the statement to the correct place && remove allow dead_code Signed-off-by: Tools-app <localhost.hutao@gmail.com> --------- Signed-off-by: Tools-app <localhost.hutao@gmail.com>
This commit is contained in:
2
.github/workflows/ksud.yml
vendored
2
.github/workflows/ksud.yml
vendored
@@ -17,6 +17,8 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ inputs.os }}
|
||||
|
||||
@@ -24,7 +24,7 @@ fn ensure_gki_kernel() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn get_kernel_version() -> Result<(i32, i32, i32)> {
|
||||
fn get_kernel_version() -> Result<(i32, i32, i32)> {
|
||||
let uname = rustix::system::uname();
|
||||
let version = uname.release().to_string_lossy();
|
||||
let re = Regex::new(r"(\d+)\.(\d+)\.(\d+)")?;
|
||||
|
||||
@@ -625,7 +625,11 @@ pub fn run() -> Result<()> {
|
||||
};
|
||||
|
||||
if let Err(e) = &result {
|
||||
log::error!("Error: {e:?}");
|
||||
for c in e.chain() {
|
||||
log::error!("{c:#?}");
|
||||
}
|
||||
|
||||
log::error!("{:#?}", e.backtrace());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::{
|
||||
use anyhow::{Result, anyhow, bail};
|
||||
use notify::{RecursiveMode, Watcher};
|
||||
|
||||
use crate::ksucalls;
|
||||
use crate::ksucalls::ksuctl;
|
||||
|
||||
pub const KPM_DIR: &str = "/data/adb/kpm";
|
||||
|
||||
@@ -20,6 +20,22 @@ const KPM_INFO: u64 = 5;
|
||||
const KPM_CONTROL: u64 = 6;
|
||||
const KPM_VERSION: u64 = 7;
|
||||
|
||||
const KSU_IOCTL_KPM: u32 = 0xc0004bc8; // _IOC(_IOC_READ|_IOC_WRITE, 'K', 200, 0)
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
struct KsuKpmCmd {
|
||||
pub control_code: u64,
|
||||
pub arg1: u64,
|
||||
pub arg2: u64,
|
||||
pub result_code: u64,
|
||||
}
|
||||
|
||||
fn kpm_ioctl(cmd: &mut KsuKpmCmd) -> std::io::Result<()> {
|
||||
ksuctl(KSU_IOCTL_KPM, cmd as *mut _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert raw kernel return code to `Result`.
|
||||
#[inline(always)]
|
||||
fn check_ret(rc: i32) -> Result<i32> {
|
||||
@@ -35,14 +51,14 @@ pub fn kpm_load(path: &str, args: Option<&str>) -> Result<()> {
|
||||
let args_c = args.map(CString::new).transpose()?;
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_LOAD,
|
||||
arg1: path_c.as_ptr() as u64,
|
||||
arg2: args_c.as_ref().map_or(0, |s| s.as_ptr() as u64),
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)?;
|
||||
println!("Success");
|
||||
Ok(())
|
||||
@@ -53,14 +69,14 @@ pub fn kpm_unload(name: &str) -> Result<()> {
|
||||
let name_c = CString::new(name)?;
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_UNLOAD,
|
||||
arg1: name_c.as_ptr() as u64,
|
||||
arg2: 0,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -68,14 +84,14 @@ pub fn kpm_unload(name: &str) -> Result<()> {
|
||||
/// Return loaded module count.
|
||||
pub fn kpm_num() -> Result<i32> {
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_NUM,
|
||||
arg1: 0,
|
||||
arg2: 0,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
let n = check_ret(result)?;
|
||||
println!("{n}");
|
||||
Ok(n)
|
||||
@@ -86,14 +102,14 @@ pub fn kpm_list() -> Result<()> {
|
||||
let mut buf = vec![0u8; 1024];
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_LIST,
|
||||
arg1: buf.as_mut_ptr() as u64,
|
||||
arg2: buf.len() as u64,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)?;
|
||||
print!("{}", buf2str(&buf));
|
||||
Ok(())
|
||||
@@ -105,14 +121,14 @@ pub fn kpm_info(name: &str) -> Result<()> {
|
||||
let mut buf = vec![0u8; 256];
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_INFO,
|
||||
arg1: name_c.as_ptr() as u64,
|
||||
arg2: buf.as_mut_ptr() as u64,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)?;
|
||||
println!("{}", buf2str(&buf));
|
||||
Ok(())
|
||||
@@ -124,14 +140,14 @@ pub fn kpm_control(name: &str, args: &str) -> Result<i32> {
|
||||
let args_c = CString::new(args)?;
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_CONTROL,
|
||||
arg1: name_c.as_ptr() as u64,
|
||||
arg2: args_c.as_ptr() as u64,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)
|
||||
}
|
||||
|
||||
@@ -140,14 +156,14 @@ pub fn kpm_version_loader() -> Result<()> {
|
||||
let mut buf = vec![0u8; 1024];
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_VERSION,
|
||||
arg1: buf.as_mut_ptr() as u64,
|
||||
arg2: buf.len() as u64,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)?;
|
||||
print!("{}", buf2str(&buf));
|
||||
Ok(())
|
||||
@@ -158,14 +174,14 @@ pub fn check_kpm_version() -> Result<String> {
|
||||
let mut buf = vec![0u8; 1024];
|
||||
|
||||
let mut result: i32 = -1;
|
||||
let mut cmd = ksucalls::KsuKpmCmd {
|
||||
let mut cmd = KsuKpmCmd {
|
||||
control_code: KPM_VERSION,
|
||||
arg1: buf.as_mut_ptr() as u64,
|
||||
arg2: buf.len() as u64,
|
||||
result_code: &mut result as *mut i32 as u64,
|
||||
};
|
||||
|
||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
||||
kpm_ioctl(&mut cmd)?;
|
||||
check_ret(result)?;
|
||||
let ver = buf2str(&buf);
|
||||
if ver.is_empty() {
|
||||
|
||||
@@ -17,10 +17,6 @@ const KSU_IOCTL_GET_FEATURE: u32 = 0xc0004b0d; // _IOC(_IOC_READ|_IOC_WRITE, 'K'
|
||||
const KSU_IOCTL_SET_FEATURE: u32 = 0x40004b0e; // _IOC(_IOC_WRITE, 'K', 14, 0)
|
||||
const KSU_IOCTL_GET_WRAPPER_FD: u32 = 0x40004b0f; // _IOC(_IOC_WRITE, 'K', 15, 0)
|
||||
const KSU_IOCTL_MANAGE_MARK: u32 = 0xc0004b10; // _IOC(_IOC_READ|_IOC_WRITE, 'K', 16, 0)
|
||||
#[allow(dead_code)]
|
||||
const KSU_IOCTL_KPM: u32 = 0xc0004bc8; // _IOC(_IOC_READ|_IOC_WRITE, 'K', 200, 0)
|
||||
#[allow(dead_code)]
|
||||
const KSU_IOCTL_UMOUNT_MANAGER: u32 = 0xc0004b6b; // _IOC(_IOC_READ|_IOC_WRITE, 'K', 107, 0)
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
@@ -134,7 +130,7 @@ fn init_driver_fd() -> Option<RawFd> {
|
||||
|
||||
// ioctl wrapper using libc
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fn ksuctl<T>(request: u32, arg: *mut T) -> std::io::Result<i32> {
|
||||
pub fn ksuctl<T>(request: u32, arg: *mut T) -> std::io::Result<i32> {
|
||||
use std::io;
|
||||
|
||||
let fd = *DRIVER_FD.get_or_init(|| init_driver_fd().unwrap_or(-1));
|
||||
@@ -298,59 +294,3 @@ pub fn mark_refresh() -> std::io::Result<()> {
|
||||
ksuctl(KSU_IOCTL_MANAGE_MARK, &mut cmd as *mut _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
#[allow(dead_code)]
|
||||
pub struct KsuKpmCmd {
|
||||
pub control_code: u64,
|
||||
pub arg1: u64,
|
||||
pub arg2: u64,
|
||||
pub result_code: u64,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn kpm_ioctl(cmd: &mut KsuKpmCmd) -> std::io::Result<()> {
|
||||
ksuctl(KSU_IOCTL_KPM, cmd as *mut _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
pub struct UmountManagerCmd {
|
||||
pub operation: u32,
|
||||
pub path: [u8; 256],
|
||||
pub check_mnt: u8,
|
||||
pub flags: i32,
|
||||
pub count: u32,
|
||||
pub entries_ptr: u64,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Default for UmountManagerCmd {
|
||||
fn default() -> Self {
|
||||
UmountManagerCmd {
|
||||
operation: 0,
|
||||
path: [0; 256],
|
||||
check_mnt: 0,
|
||||
flags: 0,
|
||||
count: 0,
|
||||
entries_ptr: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn umount_manager_ioctl(cmd: &UmountManagerCmd) -> std::io::Result<()> {
|
||||
let mut ioctl_cmd = *cmd;
|
||||
ksuctl(KSU_IOCTL_UMOUNT_MANAGER, &mut ioctl_cmd as *mut _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
#[allow(dead_code)]
|
||||
pub fn umount_manager_ioctl(_cmd: &UmountManagerCmd) -> std::io::Result<()> {
|
||||
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
}
|
||||
|
||||
@@ -60,7 +60,10 @@ struct Node {
|
||||
}
|
||||
|
||||
impl Node {
|
||||
fn collect_module_files<T: AsRef<Path>>(&mut self, module_dir: T) -> Result<bool> {
|
||||
fn collect_module_files<P>(&mut self, module_dir: P) -> Result<bool>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let dir = module_dir.as_ref();
|
||||
let mut has_file = false;
|
||||
for entry in dir.read_dir()?.flatten() {
|
||||
@@ -83,7 +86,10 @@ impl Node {
|
||||
Ok(has_file)
|
||||
}
|
||||
|
||||
fn new_root<T: ToString>(name: T) -> Self {
|
||||
fn new_root<T>(name: T) -> Self
|
||||
where
|
||||
T: ToString,
|
||||
{
|
||||
Node {
|
||||
name: name.to_string(),
|
||||
file_type: Directory,
|
||||
@@ -94,7 +100,10 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_module<T: ToString>(name: T, entry: &DirEntry) -> Option<Self> {
|
||||
fn new_module<T>(name: T, entry: &DirEntry) -> Option<Self>
|
||||
where
|
||||
T: ToString,
|
||||
{
|
||||
if let Ok(metadata) = entry.metadata() {
|
||||
let path = entry.path();
|
||||
let file_type = if metadata.file_type().is_char_device() && metadata.rdev() == 0 {
|
||||
@@ -174,7 +183,10 @@ fn collect_module_files() -> Result<Option<Node>> {
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_symlink<Src: AsRef<Path>, Dst: AsRef<Path>>(src: Src, dst: Dst) -> Result<()> {
|
||||
fn clone_symlink<P>(src: P, dst: P) -> Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let src_symlink = read_link(src.as_ref())?;
|
||||
symlink(&src_symlink, dst.as_ref())?;
|
||||
lsetfilecon(dst.as_ref(), lgetfilecon(src.as_ref())?.as_str())?;
|
||||
@@ -187,11 +199,10 @@ fn clone_symlink<Src: AsRef<Path>, Dst: AsRef<Path>>(src: Src, dst: Dst) -> Resu
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mount_mirror<P: AsRef<Path>, WP: AsRef<Path>>(
|
||||
path: P,
|
||||
work_dir_path: WP,
|
||||
entry: &DirEntry,
|
||||
) -> Result<()> {
|
||||
fn mount_mirror<P>(path: P, work_dir_path: P, entry: &DirEntry) -> Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let path = path.as_ref().join(entry.file_name());
|
||||
let work_dir_path = work_dir_path.as_ref().join(entry.file_name());
|
||||
let file_type = entry.file_type()?;
|
||||
@@ -236,12 +247,11 @@ fn mount_mirror<P: AsRef<Path>, WP: AsRef<Path>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_magic_mount<P: AsRef<Path>, WP: AsRef<Path>>(
|
||||
path: P,
|
||||
work_dir_path: WP,
|
||||
current: Node,
|
||||
has_tmpfs: bool,
|
||||
) -> Result<()> {
|
||||
fn do_magic_mount<P, WP>(path: P, work_dir_path: WP, current: Node, has_tmpfs: bool) -> Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
WP: AsRef<Path>,
|
||||
{
|
||||
let mut current = current;
|
||||
let path = path.as_ref().join(¤t.name);
|
||||
let work_dir_path = work_dir_path.as_ref().join(¤t.name);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use crate::ksucalls::UmountManagerCmd;
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::ksucalls::ksuctl;
|
||||
|
||||
const MAGIC_NUMBER_HEADER: &[u8; 4] = b"KUMT";
|
||||
const MAGIC_VERSION: u32 = 1;
|
||||
const CONFIG_FILE: &str = "/data/adb/ksu/.umount";
|
||||
const KSU_IOCTL_UMOUNT_MANAGER: u32 = 0xc0004b6b; // _IOC(_IOC_READ|_IOC_WRITE, 'K', 107, 0)
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct UmountEntry {
|
||||
@@ -27,6 +29,30 @@ pub struct UmountManager {
|
||||
defaults: Vec<UmountEntry>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct UmountManagerCmd {
|
||||
pub operation: u32,
|
||||
pub path: [u8; 256],
|
||||
pub check_mnt: u8,
|
||||
pub flags: i32,
|
||||
pub count: u32,
|
||||
pub entries_ptr: u64,
|
||||
}
|
||||
|
||||
impl Default for UmountManagerCmd {
|
||||
fn default() -> Self {
|
||||
UmountManagerCmd {
|
||||
operation: 0,
|
||||
path: [0; 256],
|
||||
check_mnt: 0,
|
||||
flags: 0,
|
||||
count: 0,
|
||||
entries_ptr: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UmountManager {
|
||||
pub fn new(config_path: Option<PathBuf>) -> Result<Self> {
|
||||
let path = config_path.unwrap_or_else(|| PathBuf::from(CONFIG_FILE));
|
||||
@@ -212,8 +238,7 @@ impl UmountManager {
|
||||
|
||||
cmd.path[..path_bytes.len()].copy_from_slice(path_bytes);
|
||||
|
||||
crate::ksucalls::umount_manager_ioctl(&cmd)
|
||||
.context(format!("Failed to add entry: {}", entry.path))?;
|
||||
umount_manager_ioctl(&cmd).context(format!("Failed to add entry: {}", entry.path))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -274,6 +299,18 @@ pub fn list_umount_paths() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fn umount_manager_ioctl(cmd: &UmountManagerCmd) -> std::io::Result<()> {
|
||||
let mut ioctl_cmd = *cmd;
|
||||
ksuctl(KSU_IOCTL_UMOUNT_MANAGER, &mut ioctl_cmd as *mut _)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
pub fn umount_manager_ioctl(_cmd: &UmountManagerCmd) -> std::io::Result<()> {
|
||||
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
}
|
||||
|
||||
pub fn clear_custom_paths() -> Result<()> {
|
||||
let mut manager = init_umount_manager()?;
|
||||
manager.clear_custom_entries()?;
|
||||
|
||||
@@ -238,7 +238,7 @@ pub fn uninstall(magiskboot_path: Option<PathBuf>) -> Result<()> {
|
||||
boot_patch::restore(None, magiskboot_path, true)?;
|
||||
println!("- Uninstall KernelSU manager..");
|
||||
Command::new("pm")
|
||||
.args(["uninstall", "me.weishu.kernelsu"])
|
||||
.args(["uninstall", "com.sukisu.ultra"])
|
||||
.spawn()?;
|
||||
println!("- Rebooting in 5 seconds..");
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
|
||||
Reference in New Issue
Block a user