ksud: restore selinux context for unlabeled module files on boot. fix #817
This commit is contained in:
@@ -165,6 +165,10 @@ pub fn on_post_data_fs() -> Result<()> {
|
|||||||
warn!("prune modules failed: {}", e);
|
warn!("prune modules failed: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Err(e) = restorecon::restorecon() {
|
||||||
|
warn!("restorecon failed: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
// load sepolicy.rule
|
// load sepolicy.rule
|
||||||
if crate::module::load_sepolicy_rule().is_err() {
|
if crate::module::load_sepolicy_rule().is_err() {
|
||||||
warn!("load sepolicy.rule failed");
|
warn!("load sepolicy.rule failed");
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ use extattr::{lsetxattr, Flags as XattrFlags};
|
|||||||
|
|
||||||
pub const SYSTEM_CON: &str = "u:object_r:system_file:s0";
|
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 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";
|
const SELINUX_XATTR: &str = "security.selinux";
|
||||||
|
|
||||||
pub fn lsetfilecon<P: AsRef<Path>>(path: P, con: &str) -> Result<()> {
|
pub fn lsetfilecon<P: AsRef<Path>>(path: P, con: &str) -> Result<()> {
|
||||||
@@ -23,6 +25,18 @@ pub fn lsetfilecon<P: AsRef<Path>>(path: P, con: &str) -> Result<()> {
|
|||||||
Ok(())
|
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"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub fn setsyscon<P: AsRef<Path>>(path: P) -> Result<()> {
|
pub fn setsyscon<P: AsRef<Path>>(path: P) -> Result<()> {
|
||||||
lsetfilecon(path, SYSTEM_CON)
|
lsetfilecon(path, SYSTEM_CON)
|
||||||
@@ -33,6 +47,11 @@ pub fn setsyscon<P: AsRef<Path>>(path: P) -> Result<()> {
|
|||||||
unimplemented!()
|
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<()> {
|
pub fn restore_syscon<P: AsRef<Path>>(dir: P) -> Result<()> {
|
||||||
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
|
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
|
||||||
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path()) {
|
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path()) {
|
||||||
@@ -41,3 +60,22 @@ pub fn restore_syscon<P: AsRef<Path>>(dir: P) -> Result<()> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn restore_syscon_if_unlabeled<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()) {
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user