From a535e14a7db49df3c8aab017e32b92d8e5bb4087 Mon Sep 17 00:00:00 2001 From: renoseven Date: Wed, 10 Apr 2024 10:25:21 +0800 Subject: [PATCH 02/17] daemon: fix 'cannot get file selinux xattr when selinux is not enforcing' issue Signed-off-by: renoseven --- syscared/src/patch/driver/kpatch/mod.rs | 10 +---- syscared/src/patch/driver/kpatch/sys.rs | 22 +++++----- upatchd/src/hijacker/kmod.rs | 57 +++++++++++++------------ upatchd/src/hijacker/mod.rs | 4 +- 4 files changed, 44 insertions(+), 49 deletions(-) diff --git a/syscared/src/patch/driver/kpatch/mod.rs b/syscared/src/patch/driver/kpatch/mod.rs index 72cbfc3..e6ab14e 100644 --- a/syscared/src/patch/driver/kpatch/mod.rs +++ b/syscared/src/patch/driver/kpatch/mod.rs @@ -17,7 +17,7 @@ use std::{ fmt::Write, }; -use anyhow::{ensure, Context, Result}; +use anyhow::{ensure, Result}; use indexmap::{indexset, IndexMap, IndexSet}; use log::debug; @@ -209,13 +209,7 @@ impl KernelPatchDriver { } pub fn apply(&mut self, patch: &KernelPatch) -> Result<()> { - let selinux_status = os::selinux::get_status()?; - if selinux_status == os::selinux::Status::Enforcing { - debug!("SELinux is enforcing"); - sys::set_security_attribute(&patch.patch_file) - .context("Kpatch: Failed to set security attribute")?; - } - + sys::selinux_relable_patch(patch)?; sys::apply_patch(patch) } diff --git a/syscared/src/patch/driver/kpatch/sys.rs b/syscared/src/patch/driver/kpatch/sys.rs index c5cde8c..5035d06 100644 --- a/syscared/src/patch/driver/kpatch/sys.rs +++ b/syscared/src/patch/driver/kpatch/sys.rs @@ -12,10 +12,7 @@ * See the Mulan PSL v2 for more details. */ -use std::{ - ffi::{CString, OsString}, - path::Path, -}; +use std::ffi::{CString, OsString}; use anyhow::{anyhow, bail, Context, Result}; use log::debug; @@ -39,15 +36,21 @@ pub fn list_kernel_modules() -> Result> { Ok(module_names) } -pub fn set_security_attribute>(patch_file: P) -> Result<()> { +pub fn selinux_relable_patch(patch: &KernelPatch) -> Result<()> { const KPATCH_PATCH_SEC_TYPE: &str = "modules_object_t"; - let file_path = patch_file.as_ref(); - let mut sec_context = os::selinux::get_security_context(file_path)?; + if os::selinux::get_status()? != os::selinux::Status::Enforcing { + return Ok(()); + } + debug!( + "Relabeling patch module '{}'...", + patch.module_name.to_string_lossy() + ); + let mut sec_context = os::selinux::get_security_context(&patch.patch_file)?; if sec_context.kind != KPATCH_PATCH_SEC_TYPE { sec_context.kind = OsString::from(KPATCH_PATCH_SEC_TYPE); - os::selinux::set_security_context(file_path, sec_context)?; + os::selinux::set_security_context(&patch.patch_file, sec_context)?; } Ok(()) @@ -85,12 +88,11 @@ fn write_patch_status(patch: &KernelPatch, value: &str) -> Result<()> { } pub fn apply_patch(patch: &KernelPatch) -> Result<()> { - let patch_module = fs::open_file(&patch.patch_file)?; - debug!( "Inserting patch module '{}'...", patch.module_name.to_string_lossy() ); + let patch_module = fs::open_file(&patch.patch_file)?; kmod::finit_module( &patch_module, CString::new("")?.as_c_str(), diff --git a/upatchd/src/hijacker/kmod.rs b/upatchd/src/hijacker/kmod.rs index 1fe4def..fc89f5f 100644 --- a/upatchd/src/hijacker/kmod.rs +++ b/upatchd/src/hijacker/kmod.rs @@ -27,50 +27,49 @@ const KMOD_SYS_PATH: &str = "/sys/module"; /// An RAII guard of the kernel module. pub struct HijackerKmodGuard { kmod_name: String, + kmod_path: PathBuf, sys_path: PathBuf, } impl HijackerKmodGuard { - pub fn new, P: AsRef>(name: S, path: P) -> Result { - let kmod_name = name.as_ref().to_string(); - let sys_path = Path::new(KMOD_SYS_PATH).join(name.as_ref()); - let kmod_path = path.as_ref().to_path_buf(); - - let instance: HijackerKmodGuard = Self { - kmod_name, - sys_path, + pub fn new, P: AsRef>(name: S, kmod_path: P) -> Result { + let instance = Self { + kmod_name: name.as_ref().to_string(), + kmod_path: kmod_path.as_ref().to_path_buf(), + sys_path: Path::new(KMOD_SYS_PATH).join(name.as_ref()), }; - if !instance.is_installed() { - instance.install(kmod_path)?; - } + instance.selinux_relabel_kmod()?; + instance.install_kmod()?; + Ok(instance) } } impl HijackerKmodGuard { - #[inline] - fn is_installed(&self) -> bool { - self.sys_path.exists() - } - - fn selinux_relable_module>(patch_file: P) -> Result<()> { + fn selinux_relabel_kmod(&self) -> Result<()> { const KMOD_SECURITY_TYPE: &str = "modules_object_t"; - let file_path = patch_file.as_ref(); - let mut sec_context = os::selinux::get_security_context(file_path)?; + if os::selinux::get_status()? != os::selinux::Status::Enforcing { + return Ok(()); + } + info!("Relabeling kernel module '{}'...", self.kmod_name); + let mut sec_context = os::selinux::get_security_context(&self.kmod_path)?; if sec_context.kind != KMOD_SECURITY_TYPE { sec_context.kind = OsString::from(KMOD_SECURITY_TYPE); - os::selinux::set_security_context(file_path, sec_context)?; + os::selinux::set_security_context(&self.kmod_path, sec_context)?; } Ok(()) } - fn install>(&self, kmod_path: P) -> Result<()> { + fn install_kmod(&self) -> Result<()> { + if self.sys_path.exists() { + return Ok(()); + } + info!("Installing kernel module '{}'...", self.kmod_name); - Self::selinux_relable_module(&kmod_path)?; - let ko_file = fs::open_file(kmod_path)?; + let ko_file = fs::open_file(&self.kmod_path)?; kmod::finit_module( &ko_file, CString::new("")?.as_c_str(), @@ -79,7 +78,11 @@ impl HijackerKmodGuard { .with_context(|| format!("Failed to install kernel module '{}'", self.kmod_name)) } - fn remove(&self) -> Result<()> { + fn remove_kmod(&self) -> Result<()> { + if !self.sys_path.exists() { + return Ok(()); + } + info!("Removing kernel module '{}'...", self.kmod_name); kmod::delete_module( CString::new(self.kmod_name.as_str())?.as_c_str(), @@ -91,10 +94,8 @@ impl HijackerKmodGuard { impl Drop for HijackerKmodGuard { fn drop(&mut self) { - if self.is_installed() { - if let Err(e) = self.remove() { - error!("{:?}", e); - } + if let Err(e) = self.remove_kmod() { + error!("{:?}", e); } } } diff --git a/upatchd/src/hijacker/mod.rs b/upatchd/src/hijacker/mod.rs index 028a4c8..8ac12e7 100644 --- a/upatchd/src/hijacker/mod.rs +++ b/upatchd/src/hijacker/mod.rs @@ -98,9 +98,7 @@ impl Hijacker { info!("Using elf mapping: {}", config); debug!("Initializing hijacker kernel module..."); - let kmod_name = KMOD_NAME.to_string(); - let kmod_path = KMOD_FILE_PATH.to_string(); - let kmod = HijackerKmodGuard::new(kmod_name, kmod_path)?; + let kmod = HijackerKmodGuard::new(KMOD_NAME, KMOD_FILE_PATH)?; debug!("Initializing hijacker ioctl channel..."); let ioctl = HijackerIoctl::new(KMOD_DEV_PATH)?; -- 2.41.0