From 06681a24906ff9506dfc7f4ffb660606df535867 Mon Sep 17 00:00:00 2001 From: weishu Date: Thu, 3 Aug 2023 11:59:17 +0800 Subject: [PATCH] ksud: restore selinux context for unlabeled module files on boot. fix #817 --- userspace/ksud/src/event.rs | 4 ++++ userspace/ksud/src/restorecon.rs | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/userspace/ksud/src/event.rs b/userspace/ksud/src/event.rs index ccce392b..78c0253e 100644 --- a/userspace/ksud/src/event.rs +++ b/userspace/ksud/src/event.rs @@ -165,6 +165,10 @@ pub fn on_post_data_fs() -> Result<()> { warn!("prune modules failed: {}", e); } + if let Err(e) = restorecon::restorecon() { + warn!("restorecon failed: {}", e); + } + // load sepolicy.rule if crate::module::load_sepolicy_rule().is_err() { warn!("load sepolicy.rule failed"); diff --git a/userspace/ksud/src/restorecon.rs b/userspace/ksud/src/restorecon.rs index 97571eda..152a7c5e 100644 --- a/userspace/ksud/src/restorecon.rs +++ b/userspace/ksud/src/restorecon.rs @@ -10,6 +10,8 @@ use extattr::{lsetxattr, Flags as XattrFlags}; 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<()> { @@ -23,6 +25,18 @@ pub fn lsetfilecon>(path: P, con: &str) -> Result<()> { 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) @@ -33,6 +47,11 @@ 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()) { @@ -41,3 +60,22 @@ pub fn restore_syscon>(dir: P) -> Result<()> { } Ok(()) } + +fn restore_syscon_if_unlabeled>(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 anyhow::Result::Ok(con) = lgetfilecon(&path) { + if con == UNLABEL_CON || con.is_empty() { + lsetfilecon(&path, SYSTEM_CON)?; + } + } + } + } + Ok(()) +} + +pub fn restorecon() -> Result<()> { + lsetfilecon(defs::DAEMON_PATH, ADB_CON)?; + restore_syscon_if_unlabeled(defs::MODULE_DIR)?; + Ok(()) +}