ksud: Fixed inconsistent parameter passing in kpm_prctl
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use libc::{c_char, c_int, c_void, prctl};
|
use libc::{c_int, c_ulong, prctl};
|
||||||
use notify::{RecursiveMode, Watcher};
|
use notify::{RecursiveMode, Watcher};
|
||||||
use std::ffi::{CStr, CString, OsStr};
|
use std::ffi::{CString, OsStr};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@@ -9,130 +9,158 @@ use std::ptr;
|
|||||||
|
|
||||||
pub const KPM_DIR: &str = "/data/adb/kpm";
|
pub const KPM_DIR: &str = "/data/adb/kpm";
|
||||||
|
|
||||||
const KSU_OPTIONS: u32 = 0xdeadbeef;
|
const KSU_OPTIONS: c_int = 0xdeadbeef_u32 as c_int;
|
||||||
const SUKISU_KPM_LOAD: i32 = 28;
|
const SUKISU_KPM_LOAD: c_int = 28;
|
||||||
const SUKISU_KPM_UNLOAD: i32 = 29;
|
const SUKISU_KPM_UNLOAD: c_int = 29;
|
||||||
const SUKISU_KPM_NUM: i32 = 30;
|
const SUKISU_KPM_NUM: c_int = 30;
|
||||||
const SUKISU_KPM_LIST: i32 = 31;
|
const SUKISU_KPM_LIST: c_int = 31;
|
||||||
const SUKISU_KPM_INFO: i32 = 32;
|
const SUKISU_KPM_INFO: c_int = 32;
|
||||||
const SUKISU_KPM_CONTROL:i32 = 33;
|
const SUKISU_KPM_CONTROL:c_int = 33;
|
||||||
const SUKISU_KPM_VERSION:i32 = 34;
|
const SUKISU_KPM_VERSION:c_int = 34;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn kpm_prctl(
|
fn check_out(out: c_int) -> Result<c_int> {
|
||||||
cmd: i32,
|
if out < 0 {
|
||||||
arg1: *const c_void,
|
bail!("KPM error: {}", std::io::Error::from_raw_os_error(-out));
|
||||||
arg2: *const c_void,
|
|
||||||
) -> Result<i32> {
|
|
||||||
let mut out: c_int = -1;
|
|
||||||
let ret = unsafe {
|
|
||||||
prctl(
|
|
||||||
KSU_OPTIONS as c_int,
|
|
||||||
cmd as c_int,
|
|
||||||
arg1,
|
|
||||||
arg2,
|
|
||||||
&mut out as *mut c_int as *mut c_void,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if ret != 0 || out < 0 {
|
|
||||||
bail!("KPM prctl error: {}", std::io::Error::from_raw_os_error(-out));
|
|
||||||
}
|
}
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn str_to_cstr<R, F: FnOnce(*const c_char) -> R>(s: &str, f: F) -> Result<R> {
|
|
||||||
let cs = CString::new(s)?;
|
|
||||||
Ok(f(cs.as_ptr()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cbuf_to_string(buf: &[u8]) -> String {
|
|
||||||
unsafe { CStr::from_ptr(buf.as_ptr() as *const c_char) }
|
|
||||||
.to_string_lossy()
|
|
||||||
.into_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kpm_load(path: &str, args: Option<&str>) -> Result<()> {
|
pub fn kpm_load(path: &str, args: Option<&str>) -> Result<()> {
|
||||||
str_to_cstr(path, |p_path| {
|
let path_c = CString::new(path)?;
|
||||||
let _args_cstring;
|
let args_c = args.map(CString::new).transpose()?;
|
||||||
let p_args = match args {
|
|
||||||
Some(a) => {
|
let mut out: c_int = -1;
|
||||||
_args_cstring = CString::new(a)?;
|
unsafe {
|
||||||
_args_cstring.as_ptr()
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
|
SUKISU_KPM_LOAD,
|
||||||
|
path_c.as_ptr() as c_ulong,
|
||||||
|
args_c.as_ref()
|
||||||
|
.map_or(ptr::null(), |s| s.as_ptr()) as c_ulong,
|
||||||
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
None => ptr::null(),
|
check_out(out)?;
|
||||||
};
|
|
||||||
unsafe { kpm_prctl(SUKISU_KPM_LOAD, p_path as _, p_args as _) }?;
|
|
||||||
println!("Success");
|
println!("Success");
|
||||||
Ok(())
|
Ok(())
|
||||||
})?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kpm_unload(name: &str) -> Result<()> {
|
pub fn kpm_unload(name: &str) -> Result<()> {
|
||||||
let _ = str_to_cstr(name, |p| unsafe {
|
let name_c = CString::new(name)?;
|
||||||
kpm_prctl(SUKISU_KPM_UNLOAD, p as _, ptr::null())
|
let mut out: c_int = -1;
|
||||||
})?;
|
unsafe {
|
||||||
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
|
SUKISU_KPM_UNLOAD,
|
||||||
|
name_c.as_ptr() as c_ulong,
|
||||||
|
0,
|
||||||
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
check_out(out)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kpm_num() -> Result<i32> {
|
pub fn kpm_num() -> Result<i32> {
|
||||||
let n = unsafe { kpm_prctl(SUKISU_KPM_NUM, ptr::null(), ptr::null())? };
|
let mut out: c_int = -1;
|
||||||
|
unsafe {
|
||||||
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
|
SUKISU_KPM_NUM,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let n = check_out(out)?;
|
||||||
println!("{}", n);
|
println!("{}", n);
|
||||||
Ok(n)
|
Ok(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kpm_list() -> Result<()> {
|
pub fn kpm_list() -> Result<()> {
|
||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
|
let mut out: c_int = -1;
|
||||||
unsafe {
|
unsafe {
|
||||||
kpm_prctl(
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
SUKISU_KPM_LIST,
|
SUKISU_KPM_LIST,
|
||||||
buf.as_mut_ptr() as _,
|
buf.as_mut_ptr() as c_ulong,
|
||||||
buf.len() as *const c_void,
|
buf.len() as c_ulong,
|
||||||
)?;
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
print!("{}", cbuf_to_string(&buf));
|
check_out(out)?;
|
||||||
|
print!("{}", buf2string(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kpm_info(name: &str) -> Result<()> {
|
pub fn kpm_info(name: &str) -> Result<()> {
|
||||||
|
let name_c = CString::new(name)?;
|
||||||
let mut buf = vec![0u8; 256];
|
let mut buf = vec![0u8; 256];
|
||||||
let _ = str_to_cstr(name, |p| unsafe {
|
let mut out: c_int = -1;
|
||||||
kpm_prctl(SUKISU_KPM_INFO, p as _, buf.as_mut_ptr() as _)
|
unsafe {
|
||||||
})?;
|
prctl(
|
||||||
println!("{}", cbuf_to_string(&buf));
|
KSU_OPTIONS,
|
||||||
|
SUKISU_KPM_INFO,
|
||||||
|
name_c.as_ptr() as c_ulong,
|
||||||
|
buf.as_mut_ptr() as c_ulong,
|
||||||
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
check_out(out)?;
|
||||||
|
println!("{}", buf2string(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kpm_control(name: &str, args: &str) -> Result<i32> {
|
pub fn kpm_control(name: &str, args: &str) -> Result<i32> {
|
||||||
str_to_cstr(name, |p_name| {
|
let name_c = CString::new(name)?;
|
||||||
str_to_cstr(args, |p_args| unsafe {
|
let args_c = CString::new(args)?;
|
||||||
kpm_prctl(SUKISU_KPM_CONTROL, p_name as _, p_args as _)
|
let mut out: c_int = -1;
|
||||||
})?
|
unsafe {
|
||||||
})?
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
|
SUKISU_KPM_CONTROL,
|
||||||
|
name_c.as_ptr() as c_ulong,
|
||||||
|
args_c.as_ptr() as c_ulong,
|
||||||
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
check_out(out)?;
|
||||||
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kpm_version_loader() -> Result<()> {
|
pub fn kpm_version_loader() -> Result<()> {
|
||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
|
let mut out: c_int = -1;
|
||||||
unsafe {
|
unsafe {
|
||||||
kpm_prctl(
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
SUKISU_KPM_VERSION,
|
SUKISU_KPM_VERSION,
|
||||||
buf.as_mut_ptr() as _,
|
buf.as_mut_ptr() as c_ulong,
|
||||||
buf.len() as *const c_void,
|
buf.len() as c_ulong,
|
||||||
)?;
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
print!("{}", cbuf_to_string(&buf));
|
check_out(out)?;
|
||||||
|
print!("{}", buf2string(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_kpm_version() -> Result<String> {
|
pub fn check_kpm_version() -> Result<String> {
|
||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
|
let mut out: c_int = -1;
|
||||||
unsafe {
|
unsafe {
|
||||||
kpm_prctl(
|
prctl(
|
||||||
|
KSU_OPTIONS,
|
||||||
SUKISU_KPM_VERSION,
|
SUKISU_KPM_VERSION,
|
||||||
buf.as_mut_ptr() as _,
|
buf.as_mut_ptr() as c_ulong,
|
||||||
buf.len() as *const c_void,
|
buf.len() as c_ulong,
|
||||||
)?;
|
&mut out as *mut c_int as c_ulong,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let ver = cbuf_to_string(&buf);
|
check_out(out)?;
|
||||||
|
let ver = buf2string(&buf);
|
||||||
if ver.is_empty() || ver.starts_with("Error") {
|
if ver.is_empty() || ver.starts_with("Error") {
|
||||||
bail!("KPM: Invalid version response: {}", ver);
|
bail!("KPM: Invalid version response: {}", ver);
|
||||||
}
|
}
|
||||||
@@ -153,7 +181,7 @@ pub fn ensure_kpm_dir() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_kpm_watcher() -> Result<()> {
|
pub fn start_kpm_watcher() -> Result<()> {
|
||||||
check_kpm_version()?;
|
check_kpm_version()?; // 版本不对直接返回
|
||||||
ensure_kpm_dir()?;
|
ensure_kpm_dir()?;
|
||||||
if crate::utils::is_safe_mode() {
|
if crate::utils::is_safe_mode() {
|
||||||
log::warn!("KPM: Safe mode – removing all KPM modules");
|
log::warn!("KPM: Safe mode – removing all KPM modules");
|
||||||
@@ -261,3 +289,11 @@ pub fn load_kpm_modules() -> Result<()> {
|
|||||||
log::info!("KPM: Load done – ok: {}, failed: {}", ok, ng);
|
log::info!("KPM: Load done – ok: {}, failed: {}", ok, ng);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn buf2string(buf: &[u8]) -> String {
|
||||||
|
unsafe {
|
||||||
|
std::ffi::CStr::from_ptr(buf.as_ptr() as *const _)
|
||||||
|
.to_string_lossy()
|
||||||
|
.into_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user