Add UID scanner functionality and related infrastructure
- Introduced a new module `uid_scanner` in userspace for managing UID scanning. - Created a new GitHub Actions workflow for building the `user_scanner`. - Implemented kernel communication in `throne_comm.c` and `throne_comm.h` to handle user space updates and rescan requests. - Developed the `uid_scanner` daemon in C to scan user directories and manage UID whitelists. - Added configuration management for the UID scanner with support for multiple users and auto-scanning. - Implemented logging and error handling throughout the UID scanning process. - Created necessary build files for the `user_scanner` JNI integration. - Added a `.gitignore` file to exclude build artifacts.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use crate::defs::{KSU_MOUNT_SOURCE, NO_MOUNT_PATH, NO_TMPFS_PATH};
|
||||
use crate::kpm;
|
||||
use crate::module::{handle_updated_modules, prune_modules};
|
||||
use crate::{assets, defs, ksucalls, restorecon, utils};
|
||||
use crate::{assets, defs, ksucalls, restorecon, utils, kpm, uid_scanner};
|
||||
use anyhow::{Context, Result};
|
||||
use log::{info, warn};
|
||||
use rustix::fs::{MountFlags, mount};
|
||||
@@ -35,6 +34,9 @@ pub fn on_post_data_fs() -> Result<()> {
|
||||
|
||||
assets::ensure_binaries(true).with_context(|| "Failed to extract bin assets")?;
|
||||
|
||||
// Start UID scanner daemon with highest priority
|
||||
uid_scanner::start_uid_scanner_daemon()?;
|
||||
|
||||
// tell kernel that we've mount the module, so that it can do some optimization
|
||||
ksucalls::report_module_mounted();
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ mod restorecon;
|
||||
mod sepolicy;
|
||||
mod su;
|
||||
mod utils;
|
||||
mod uid_scanner;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
cli::run()
|
||||
|
||||
91
userspace/ksud/src/uid_scanner.rs
Normal file
91
userspace/ksud/src/uid_scanner.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use crate::utils;
|
||||
use anyhow::{Context, Result};
|
||||
use log::{info, warn};
|
||||
use std::{
|
||||
fs,
|
||||
io::Write,
|
||||
os::unix::{
|
||||
fs::{symlink, PermissionsExt},
|
||||
process::CommandExt,
|
||||
},
|
||||
path::Path,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
pub fn start_uid_scanner_daemon() -> Result<()> {
|
||||
const SCANNER_PATH: &str = "/data/adb/uid_scanner";
|
||||
const LINK_DIR: &str = "/data/adb/ksu/bin";
|
||||
const LINK_PATH: &str = "/data/adb/ksu/bin/uid_scanner";
|
||||
const SERVICE_DIR: &str = "/data/adb/service.d";
|
||||
const SERVICE_PATH: &str = "/data/adb/service.d/uid_scanner.sh";
|
||||
|
||||
if !Path::new(SCANNER_PATH).exists() {
|
||||
warn!("uid scanner binary not found at {}", SCANNER_PATH);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Err(e) = fs::set_permissions(SCANNER_PATH, fs::Permissions::from_mode(0o755)) {
|
||||
warn!("failed to set permissions for {}: {}", SCANNER_PATH, e);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
if let Err(e) = fs::create_dir_all(LINK_DIR) {
|
||||
warn!("failed to create {}: {}", LINK_DIR, e);
|
||||
} else if !Path::new(LINK_PATH).exists() {
|
||||
match symlink(SCANNER_PATH, LINK_PATH) {
|
||||
Ok(_) => info!("created symlink {} -> {}", SCANNER_PATH, LINK_PATH),
|
||||
Err(e) => warn!("failed to create symlink: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = fs::create_dir_all(SERVICE_DIR) {
|
||||
warn!("failed to create {}: {}", SERVICE_DIR, e);
|
||||
} else if !Path::new(SERVICE_PATH).exists() {
|
||||
let content = r#"#!/system/bin/sh
|
||||
# KSU uid_scanner auto-restart script
|
||||
until [ -d "/sdcard/Android" ]; do sleep 1; done
|
||||
sleep 10
|
||||
/data/adb/uid_scanner restart
|
||||
"#;
|
||||
match fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(SERVICE_PATH)
|
||||
.and_then(|mut f| {
|
||||
f.write_all(content.as_bytes())?;
|
||||
f.sync_all()?;
|
||||
fs::set_permissions(SERVICE_PATH, fs::Permissions::from_mode(0o755))
|
||||
}) {
|
||||
Ok(_) => info!("created service script {}", SERVICE_PATH),
|
||||
Err(e) => warn!("failed to write {}: {}", SERVICE_PATH, e),
|
||||
}
|
||||
}
|
||||
|
||||
info!("starting uid scanner daemon with highest priority");
|
||||
let mut cmd = Command::new(SCANNER_PATH);
|
||||
cmd.arg("start")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.current_dir("/");
|
||||
|
||||
unsafe {
|
||||
cmd.pre_exec(|| {
|
||||
libc::nice(-20);
|
||||
libc::setsid();
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
match cmd.spawn() {
|
||||
Ok(child) => {
|
||||
info!("uid scanner daemon started with pid: {}", child.id());
|
||||
std::mem::drop(child);
|
||||
}
|
||||
Err(e) => warn!("failed to start uid scanner daemon: {}", e),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user