* chore: make cargo clippy happy Signed-off-by: Tools-app <localhost.hutao@gmail.com> * chore: Optimize import - Format as a standard import Signed-off-by: Tools-app <localhost.hutao@gmail.com> --------- Signed-off-by: Tools-app <localhost.hutao@gmail.com>
82 lines
2.5 KiB
Rust
82 lines
2.5 KiB
Rust
use std::path::Path;
|
|
|
|
use anyhow::Result;
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
use anyhow::{Context, Ok};
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
use extattr::{Flags as XattrFlags, lsetxattr};
|
|
use jwalk::{Parallelism::Serial, WalkDir};
|
|
|
|
use crate::defs;
|
|
|
|
pub const SYSTEM_CON: &str = "u:object_r:system_file:s0";
|
|
pub const ADB_CON: &str = "u:object_r:adb_data_file:s0";
|
|
pub const UNLABEL_CON: &str = "u:object_r:unlabeled:s0";
|
|
|
|
const SELINUX_XATTR: &str = "security.selinux";
|
|
|
|
pub fn lsetfilecon<P: AsRef<Path>>(path: P, con: &str) -> Result<()> {
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
lsetxattr(&path, SELINUX_XATTR, con, XattrFlags::empty()).with_context(|| {
|
|
format!(
|
|
"Failed to change SELinux context for {}",
|
|
path.as_ref().display()
|
|
)
|
|
})?;
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
pub fn lgetfilecon<P: AsRef<Path>>(path: P) -> Result<String> {
|
|
let con = extattr::lgetxattr(&path, SELINUX_XATTR).with_context(|| {
|
|
format!(
|
|
"Failed to get SELinux context for {}",
|
|
path.as_ref().display()
|
|
)
|
|
})?;
|
|
let con = String::from_utf8_lossy(&con);
|
|
Ok(con.to_string())
|
|
}
|
|
|
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
pub fn setsyscon<P: AsRef<Path>>(path: P) -> Result<()> {
|
|
lsetfilecon(path, SYSTEM_CON)
|
|
}
|
|
|
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
|
pub fn setsyscon<P: AsRef<Path>>(path: P) -> Result<()> {
|
|
unimplemented!()
|
|
}
|
|
|
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
|
pub fn lgetfilecon<P: AsRef<Path>>(path: P) -> Result<String> {
|
|
unimplemented!()
|
|
}
|
|
|
|
pub fn restore_syscon<P: AsRef<Path>>(dir: P) -> Result<()> {
|
|
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
|
|
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path()) {
|
|
setsyscon(&path)?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn restore_modules_con<P: AsRef<Path>>(dir: P) -> Result<()> {
|
|
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
|
|
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path())
|
|
&& let Result::Ok(con) = lgetfilecon(&path)
|
|
&& (con == ADB_CON || con == UNLABEL_CON || con.is_empty())
|
|
{
|
|
lsetfilecon(&path, SYSTEM_CON)?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn restorecon() -> Result<()> {
|
|
lsetfilecon(defs::DAEMON_PATH, ADB_CON)?;
|
|
restore_modules_con(defs::MODULE_DIR)?;
|
|
Ok(())
|
|
}
|