diff --git a/.github/workflows/ksud.yml b/.github/workflows/ksud.yml index 44d2967f..87439f4b 100644 --- a/.github/workflows/ksud.yml +++ b/.github/workflows/ksud.yml @@ -17,6 +17,8 @@ on: required: false type: boolean default: true +env: + CARGO_TERM_COLOR: always jobs: build: runs-on: ${{ inputs.os }} diff --git a/userspace/ksud/src/boot_patch.rs b/userspace/ksud/src/boot_patch.rs index 8d05e91e..531b4229 100644 --- a/userspace/ksud/src/boot_patch.rs +++ b/userspace/ksud/src/boot_patch.rs @@ -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+)")?; diff --git a/userspace/ksud/src/cli.rs b/userspace/ksud/src/cli.rs index 53b21f65..dd64aae0 100644 --- a/userspace/ksud/src/cli.rs +++ b/userspace/ksud/src/cli.rs @@ -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 } diff --git a/userspace/ksud/src/kpm.rs b/userspace/ksud/src/kpm.rs index 5c1f2b10..195d1ea7 100644 --- a/userspace/ksud/src/kpm.rs +++ b/userspace/ksud/src/kpm.rs @@ -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 { @@ -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 { 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 { 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 { 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() { diff --git a/userspace/ksud/src/ksucalls.rs b/userspace/ksud/src/ksucalls.rs index 991d4ed5..401bfe99 100644 --- a/userspace/ksud/src/ksucalls.rs +++ b/userspace/ksud/src/ksucalls.rs @@ -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 { // ioctl wrapper using libc #[cfg(any(target_os = "linux", target_os = "android"))] -fn ksuctl(request: u32, arg: *mut T) -> std::io::Result { +pub fn ksuctl(request: u32, arg: *mut T) -> std::io::Result { 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)) -} diff --git a/userspace/ksud/src/magic_mount.rs b/userspace/ksud/src/magic_mount.rs index 484f2a2a..8ca539ed 100644 --- a/userspace/ksud/src/magic_mount.rs +++ b/userspace/ksud/src/magic_mount.rs @@ -60,7 +60,10 @@ struct Node { } impl Node { - fn collect_module_files>(&mut self, module_dir: T) -> Result { + fn collect_module_files

(&mut self, module_dir: P) -> Result + where + P: AsRef, + { 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(name: T) -> Self { + fn new_root(name: T) -> Self + where + T: ToString, + { Node { name: name.to_string(), file_type: Directory, @@ -94,7 +100,10 @@ impl Node { } } - fn new_module(name: T, entry: &DirEntry) -> Option { + fn new_module(name: T, entry: &DirEntry) -> Option + 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> { } } -fn clone_symlink, Dst: AsRef>(src: Src, dst: Dst) -> Result<()> { +fn clone_symlink

(src: P, dst: P) -> Result<()> +where + P: AsRef, +{ 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, Dst: AsRef>(src: Src, dst: Dst) -> Resu Ok(()) } -fn mount_mirror, WP: AsRef>( - path: P, - work_dir_path: WP, - entry: &DirEntry, -) -> Result<()> { +fn mount_mirror

(path: P, work_dir_path: P, entry: &DirEntry) -> Result<()> +where + P: AsRef, +{ 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, WP: AsRef>( Ok(()) } -fn do_magic_mount, WP: AsRef>( - path: P, - work_dir_path: WP, - current: Node, - has_tmpfs: bool, -) -> Result<()> { +fn do_magic_mount(path: P, work_dir_path: WP, current: Node, has_tmpfs: bool) -> Result<()> +where + P: AsRef, + WP: AsRef, +{ let mut current = current; let path = path.as_ref().join(¤t.name); let work_dir_path = work_dir_path.as_ref().join(¤t.name); diff --git a/userspace/ksud/src/umount_manager.rs b/userspace/ksud/src/umount_manager.rs index 09df4245..d2c30064 100644 --- a/userspace/ksud/src/umount_manager.rs +++ b/userspace/ksud/src/umount_manager.rs @@ -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, } +#[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) -> Result { 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()?; diff --git a/userspace/ksud/src/utils.rs b/userspace/ksud/src/utils.rs index 9c09e58b..307a05ee 100644 --- a/userspace/ksud/src/utils.rs +++ b/userspace/ksud/src/utils.rs @@ -238,7 +238,7 @@ pub fn uninstall(magiskboot_path: Option) -> 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));