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
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
default: true
|
default: true
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ${{ inputs.os }}
|
runs-on: ${{ inputs.os }}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ fn ensure_gki_kernel() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[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 uname = rustix::system::uname();
|
||||||
let version = uname.release().to_string_lossy();
|
let version = uname.release().to_string_lossy();
|
||||||
let re = Regex::new(r"(\d+)\.(\d+)\.(\d+)")?;
|
let re = Regex::new(r"(\d+)\.(\d+)\.(\d+)")?;
|
||||||
|
|||||||
@@ -625,7 +625,11 @@ pub fn run() -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = &result {
|
if let Err(e) = &result {
|
||||||
log::error!("Error: {e:?}");
|
for c in e.chain() {
|
||||||
|
log::error!("{c:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
log::error!("{:#?}", e.backtrace());
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::{
|
|||||||
use anyhow::{Result, anyhow, bail};
|
use anyhow::{Result, anyhow, bail};
|
||||||
use notify::{RecursiveMode, Watcher};
|
use notify::{RecursiveMode, Watcher};
|
||||||
|
|
||||||
use crate::ksucalls;
|
use crate::ksucalls::ksuctl;
|
||||||
|
|
||||||
pub const KPM_DIR: &str = "/data/adb/kpm";
|
pub const KPM_DIR: &str = "/data/adb/kpm";
|
||||||
|
|
||||||
@@ -20,6 +20,22 @@ const KPM_INFO: u64 = 5;
|
|||||||
const KPM_CONTROL: u64 = 6;
|
const KPM_CONTROL: u64 = 6;
|
||||||
const KPM_VERSION: u64 = 7;
|
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`.
|
/// Convert raw kernel return code to `Result`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn check_ret(rc: i32) -> Result<i32> {
|
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 args_c = args.map(CString::new).transpose()?;
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_LOAD,
|
control_code: KPM_LOAD,
|
||||||
arg1: path_c.as_ptr() as u64,
|
arg1: path_c.as_ptr() as u64,
|
||||||
arg2: args_c.as_ref().map_or(0, |s| s.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,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)?;
|
check_ret(result)?;
|
||||||
println!("Success");
|
println!("Success");
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -53,14 +69,14 @@ pub fn kpm_unload(name: &str) -> Result<()> {
|
|||||||
let name_c = CString::new(name)?;
|
let name_c = CString::new(name)?;
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_UNLOAD,
|
control_code: KPM_UNLOAD,
|
||||||
arg1: name_c.as_ptr() as u64,
|
arg1: name_c.as_ptr() as u64,
|
||||||
arg2: 0,
|
arg2: 0,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)?;
|
check_ret(result)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -68,14 +84,14 @@ pub fn kpm_unload(name: &str) -> Result<()> {
|
|||||||
/// Return loaded module count.
|
/// Return loaded module count.
|
||||||
pub fn kpm_num() -> Result<i32> {
|
pub fn kpm_num() -> Result<i32> {
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_NUM,
|
control_code: KPM_NUM,
|
||||||
arg1: 0,
|
arg1: 0,
|
||||||
arg2: 0,
|
arg2: 0,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
let n = check_ret(result)?;
|
let n = check_ret(result)?;
|
||||||
println!("{n}");
|
println!("{n}");
|
||||||
Ok(n)
|
Ok(n)
|
||||||
@@ -86,14 +102,14 @@ pub fn kpm_list() -> Result<()> {
|
|||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_LIST,
|
control_code: KPM_LIST,
|
||||||
arg1: buf.as_mut_ptr() as u64,
|
arg1: buf.as_mut_ptr() as u64,
|
||||||
arg2: buf.len() as u64,
|
arg2: buf.len() as u64,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)?;
|
check_ret(result)?;
|
||||||
print!("{}", buf2str(&buf));
|
print!("{}", buf2str(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -105,14 +121,14 @@ pub fn kpm_info(name: &str) -> Result<()> {
|
|||||||
let mut buf = vec![0u8; 256];
|
let mut buf = vec![0u8; 256];
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_INFO,
|
control_code: KPM_INFO,
|
||||||
arg1: name_c.as_ptr() as u64,
|
arg1: name_c.as_ptr() as u64,
|
||||||
arg2: buf.as_mut_ptr() as u64,
|
arg2: buf.as_mut_ptr() as u64,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)?;
|
check_ret(result)?;
|
||||||
println!("{}", buf2str(&buf));
|
println!("{}", buf2str(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -124,14 +140,14 @@ pub fn kpm_control(name: &str, args: &str) -> Result<i32> {
|
|||||||
let args_c = CString::new(args)?;
|
let args_c = CString::new(args)?;
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_CONTROL,
|
control_code: KPM_CONTROL,
|
||||||
arg1: name_c.as_ptr() as u64,
|
arg1: name_c.as_ptr() as u64,
|
||||||
arg2: args_c.as_ptr() as u64,
|
arg2: args_c.as_ptr() as u64,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)
|
check_ret(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,14 +156,14 @@ pub fn kpm_version_loader() -> Result<()> {
|
|||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_VERSION,
|
control_code: KPM_VERSION,
|
||||||
arg1: buf.as_mut_ptr() as u64,
|
arg1: buf.as_mut_ptr() as u64,
|
||||||
arg2: buf.len() as u64,
|
arg2: buf.len() as u64,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)?;
|
check_ret(result)?;
|
||||||
print!("{}", buf2str(&buf));
|
print!("{}", buf2str(&buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -158,14 +174,14 @@ pub fn check_kpm_version() -> Result<String> {
|
|||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
|
|
||||||
let mut result: i32 = -1;
|
let mut result: i32 = -1;
|
||||||
let mut cmd = ksucalls::KsuKpmCmd {
|
let mut cmd = KsuKpmCmd {
|
||||||
control_code: KPM_VERSION,
|
control_code: KPM_VERSION,
|
||||||
arg1: buf.as_mut_ptr() as u64,
|
arg1: buf.as_mut_ptr() as u64,
|
||||||
arg2: buf.len() as u64,
|
arg2: buf.len() as u64,
|
||||||
result_code: &mut result as *mut i32 as u64,
|
result_code: &mut result as *mut i32 as u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
ksucalls::kpm_ioctl(&mut cmd)?;
|
kpm_ioctl(&mut cmd)?;
|
||||||
check_ret(result)?;
|
check_ret(result)?;
|
||||||
let ver = buf2str(&buf);
|
let ver = buf2str(&buf);
|
||||||
if ver.is_empty() {
|
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_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_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)
|
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)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
@@ -134,7 +130,7 @@ fn init_driver_fd() -> Option<RawFd> {
|
|||||||
|
|
||||||
// ioctl wrapper using libc
|
// ioctl wrapper using libc
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[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;
|
use std::io;
|
||||||
|
|
||||||
let fd = *DRIVER_FD.get_or_init(|| init_driver_fd().unwrap_or(-1));
|
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 _)?;
|
ksuctl(KSU_IOCTL_MANAGE_MARK, &mut cmd as *mut _)?;
|
||||||
Ok(())
|
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 {
|
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 dir = module_dir.as_ref();
|
||||||
let mut has_file = false;
|
let mut has_file = false;
|
||||||
for entry in dir.read_dir()?.flatten() {
|
for entry in dir.read_dir()?.flatten() {
|
||||||
@@ -83,7 +86,10 @@ impl Node {
|
|||||||
Ok(has_file)
|
Ok(has_file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_root<T: ToString>(name: T) -> Self {
|
fn new_root<T>(name: T) -> Self
|
||||||
|
where
|
||||||
|
T: ToString,
|
||||||
|
{
|
||||||
Node {
|
Node {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
file_type: Directory,
|
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() {
|
if let Ok(metadata) = entry.metadata() {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
let file_type = if metadata.file_type().is_char_device() && metadata.rdev() == 0 {
|
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())?;
|
let src_symlink = read_link(src.as_ref())?;
|
||||||
symlink(&src_symlink, dst.as_ref())?;
|
symlink(&src_symlink, dst.as_ref())?;
|
||||||
lsetfilecon(dst.as_ref(), lgetfilecon(src.as_ref())?.as_str())?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mount_mirror<P: AsRef<Path>, WP: AsRef<Path>>(
|
fn mount_mirror<P>(path: P, work_dir_path: P, entry: &DirEntry) -> Result<()>
|
||||||
path: P,
|
where
|
||||||
work_dir_path: WP,
|
P: AsRef<Path>,
|
||||||
entry: &DirEntry,
|
{
|
||||||
) -> Result<()> {
|
|
||||||
let path = path.as_ref().join(entry.file_name());
|
let path = path.as_ref().join(entry.file_name());
|
||||||
let work_dir_path = work_dir_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()?;
|
let file_type = entry.file_type()?;
|
||||||
@@ -236,12 +247,11 @@ fn mount_mirror<P: AsRef<Path>, WP: AsRef<Path>>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_magic_mount<P: AsRef<Path>, WP: AsRef<Path>>(
|
fn do_magic_mount<P, WP>(path: P, work_dir_path: WP, current: Node, has_tmpfs: bool) -> Result<()>
|
||||||
path: P,
|
where
|
||||||
work_dir_path: WP,
|
P: AsRef<Path>,
|
||||||
current: Node,
|
WP: AsRef<Path>,
|
||||||
has_tmpfs: bool,
|
{
|
||||||
) -> Result<()> {
|
|
||||||
let mut current = current;
|
let mut current = current;
|
||||||
let path = path.as_ref().join(¤t.name);
|
let path = path.as_ref().join(¤t.name);
|
||||||
let work_dir_path = work_dir_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 anyhow::{Context, Result, anyhow};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use crate::ksucalls::ksuctl;
|
||||||
|
|
||||||
const MAGIC_NUMBER_HEADER: &[u8; 4] = b"KUMT";
|
const MAGIC_NUMBER_HEADER: &[u8; 4] = b"KUMT";
|
||||||
const MAGIC_VERSION: u32 = 1;
|
const MAGIC_VERSION: u32 = 1;
|
||||||
const CONFIG_FILE: &str = "/data/adb/ksu/.umount";
|
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)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct UmountEntry {
|
pub struct UmountEntry {
|
||||||
@@ -27,6 +29,30 @@ pub struct UmountManager {
|
|||||||
defaults: Vec<UmountEntry>,
|
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 {
|
impl UmountManager {
|
||||||
pub fn new(config_path: Option<PathBuf>) -> Result<Self> {
|
pub fn new(config_path: Option<PathBuf>) -> Result<Self> {
|
||||||
let path = config_path.unwrap_or_else(|| PathBuf::from(CONFIG_FILE));
|
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);
|
cmd.path[..path_bytes.len()].copy_from_slice(path_bytes);
|
||||||
|
|
||||||
crate::ksucalls::umount_manager_ioctl(&cmd)
|
umount_manager_ioctl(&cmd).context(format!("Failed to add entry: {}", entry.path))?;
|
||||||
.context(format!("Failed to add entry: {}", entry.path))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -274,6 +299,18 @@ pub fn list_umount_paths() -> Result<()> {
|
|||||||
Ok(())
|
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<()> {
|
pub fn clear_custom_paths() -> Result<()> {
|
||||||
let mut manager = init_umount_manager()?;
|
let mut manager = init_umount_manager()?;
|
||||||
manager.clear_custom_entries()?;
|
manager.clear_custom_entries()?;
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ pub fn uninstall(magiskboot_path: Option<PathBuf>) -> Result<()> {
|
|||||||
boot_patch::restore(None, magiskboot_path, true)?;
|
boot_patch::restore(None, magiskboot_path, true)?;
|
||||||
println!("- Uninstall KernelSU manager..");
|
println!("- Uninstall KernelSU manager..");
|
||||||
Command::new("pm")
|
Command::new("pm")
|
||||||
.args(["uninstall", "me.weishu.kernelsu"])
|
.args(["uninstall", "com.sukisu.ultra"])
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
println!("- Rebooting in 5 seconds..");
|
println!("- Rebooting in 5 seconds..");
|
||||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||||
|
|||||||
Reference in New Issue
Block a user