diff --git a/userspace/ksud/src/cli.rs b/userspace/ksud/src/cli.rs index acacc3ad..e9456ad5 100644 --- a/userspace/ksud/src/cli.rs +++ b/userspace/ksud/src/cli.rs @@ -8,7 +8,9 @@ use android_logger::Config; use log::LevelFilter; use crate::boot_patch::{BootPatchArgs, BootRestoreArgs}; -use crate::{apk_sign, assets, debug, defs, init_event, ksucalls, module, module_config, utils}; +use crate::{ + apk_sign, assets, debug, defs, init_event, ksucalls, module, module_config, susfs, utils, +}; /// KernelSU userspace cli #[derive(Parser, Debug)] @@ -35,6 +37,12 @@ enum Commands { /// Trigger `boot-complete` event BootCompleted, + /// Susfs + Susfs { + #[command(subcommand)] + command: Susfs, + }, + /// Install KernelSU userspace component to system Install { #[arg(long, default_value = None)] @@ -432,6 +440,16 @@ mod kpm_cmd { } } +#[derive(clap::Subcommand, Debug)] +enum Susfs { + /// Get SUSFS Status + Status, + /// Get SUSFS Version + Version, + /// Get SUSFS enable Features + Features, +} + #[derive(clap::Subcommand, Debug)] enum Umount { /// Add custom umount path @@ -496,7 +514,18 @@ pub fn run() -> Result<()> { init_event::on_boot_completed(); Ok(()) } - + Commands::Susfs { command } => { + match command { + Susfs::Version => { + println!("{}", susfs::get_susfs_version()) + } + Susfs::Status => { + println!("{}", susfs::get_susfs_status()) + } + Susfs::Features => susfs::get_susfs_features(), + } + Ok(()) + } Commands::Module { command } => { #[cfg(any(target_os = "linux", target_os = "android"))] { diff --git a/userspace/ksud/src/main.rs b/userspace/ksud/src/main.rs index a77c4080..041dc3f2 100644 --- a/userspace/ksud/src/main.rs +++ b/userspace/ksud/src/main.rs @@ -17,6 +17,7 @@ mod cli; mod debug; mod defs; mod feature; +mod susfs; mod init_event; #[cfg(target_arch = "aarch64")] mod kpm; diff --git a/userspace/ksud/src/susfs.rs b/userspace/ksud/src/susfs.rs new file mode 100644 index 00000000..76991210 --- /dev/null +++ b/userspace/ksud/src/susfs.rs @@ -0,0 +1,81 @@ +use anyhow::Result; +use libc::SYS_reboot; + +const SUSFS_MAX_VERSION_BUFSIZE: usize = 16; +const SUSFS_ENABLED_FEATURES_SIZE: usize = 8192; +const ERR_CMD_NOT_SUPPORTED: i32 = 126; +const KSU_INSTALL_MAGIC1: u32 = 0xDEADBEEF; +const CMD_SUSFS_SHOW_VERSION: u32 = 0x555e1; +const CMD_SUSFS_SHOW_ENABLED_FEATURES: u32 = 0x555e2; +const SUSFS_MAGIC: u32 = 0xFAFAFAFA; + +#[repr(C)] +struct SusfsVersion { + susfs_version: [u8; SUSFS_MAX_VERSION_BUFSIZE], + err: i32, +} + +#[repr(C)] +struct SusfsFeatures { + enabled_features: [u8; SUSFS_ENABLED_FEATURES_SIZE], + err: i32, +} + +pub fn get_susfs_version() -> usize { + let mut cmd = SusfsVersion { + susfs_version: [0; SUSFS_MAX_VERSION_BUFSIZE], + err: ERR_CMD_NOT_SUPPORTED, + }; + + let ret = unsafe { + libc::syscall( + SYS_reboot, + KSU_INSTALL_MAGIC1, + SUSFS_MAGIC, + CMD_SUSFS_SHOW_VERSION, + &mut cmd, + ) + }; + + if ret < 0 { + return 0; + } + + let ver = cmd.susfs_version.iter().position(|&b| b == 0).unwrap_or(16); + std::str::from_utf8(&cmd.susfs_version[..ver]).unwrap_or(""); + + ver +} + +pub fn get_susfs_status() -> bool { + if get_susfs_version() < 0 { false } else { true } +} + +pub fn get_susfs_features() { + let mut cmd = SusfsFeatures { + enabled_features: [0; SUSFS_ENABLED_FEATURES_SIZE], + err: ERR_CMD_NOT_SUPPORTED, + }; + + let ret = unsafe { + libc::syscall( + SYS_reboot, + KSU_INSTALL_MAGIC1, + SUSFS_MAGIC, + CMD_SUSFS_SHOW_ENABLED_FEATURES, + &mut cmd, + ) + }; + + if ret < 0 { + return; + } + + let features = cmd + .enabled_features + .iter() + .position(|&b| b == 0) + .unwrap_or(16); + std::str::from_utf8(&cmd.enabled_features[..features]).unwrap_or(""); + println!("{}", features); +}