use crate::defs; use anyhow::Result; use jwalk::{Parallelism::Serial, WalkDir}; use std::path::Path; #[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}; 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>(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>(path: P) -> Result { 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>(path: P) -> Result<()> { lsetfilecon(path, SYSTEM_CON) } #[cfg(not(any(target_os = "linux", target_os = "android")))] pub fn setsyscon>(path: P) -> Result<()> { unimplemented!() } #[cfg(not(any(target_os = "linux", target_os = "android")))] pub fn lgetfilecon>(path: P) -> Result { unimplemented!() } pub fn restore_syscon>(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>(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()) { if let Result::Ok(con) = lgetfilecon(&path) { if 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(()) }