220 lines
7.6 KiB
Diff
220 lines
7.6 KiB
Diff
From a535e14a7db49df3c8aab017e32b92d8e5bb4087 Mon Sep 17 00:00:00 2001
|
|
From: renoseven <dev@renoseven.net>
|
|
Date: Wed, 10 Apr 2024 10:25:21 +0800
|
|
Subject: [PATCH 02/10] daemon: fix 'cannot get file selinux xattr when selinux
|
|
is not enforcing' issue
|
|
|
|
Signed-off-by: renoseven <dev@renoseven.net>
|
|
---
|
|
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<Vec<OsString>> {
|
|
Ok(module_names)
|
|
}
|
|
|
|
-pub fn set_security_attribute<P: AsRef<Path>>(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<S: AsRef<str>, P: AsRef<Path>>(name: S, path: P) -> Result<Self> {
|
|
- 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<S: AsRef<str>, P: AsRef<Path>>(name: S, kmod_path: P) -> Result<Self> {
|
|
+ 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<P: AsRef<Path>>(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<P: AsRef<Path>>(&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
|
|
|