update to 1.2.1-3
This commit is contained in:
parent
c90659c550
commit
5e13351958
33
0001-upatch-hijacker-fix-compile-bug.patch
Normal file
33
0001-upatch-hijacker-fix-compile-bug.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From 8c09e8b3d9d59012c1019c01ac2246c770501c75 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ningyu <405888464@qq.com>
|
||||||
|
Date: Sun, 7 Apr 2024 10:50:13 +0800
|
||||||
|
Subject: [PATCH 01/10] upatch-hijacker: fix compile bug container_of_safe =>
|
||||||
|
container_of
|
||||||
|
|
||||||
|
---
|
||||||
|
upatch-hijacker/ko/map.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/upatch-hijacker/ko/map.c b/upatch-hijacker/ko/map.c
|
||||||
|
index a9c18ba..3049556 100644
|
||||||
|
--- a/upatch-hijacker/ko/map.c
|
||||||
|
+++ b/upatch-hijacker/ko/map.c
|
||||||
|
@@ -70,7 +70,7 @@ static inline void remove_entry(struct map_entry *entry)
|
||||||
|
|
||||||
|
static inline void release_entry(struct kref *kref)
|
||||||
|
{
|
||||||
|
- remove_entry(container_of_safe(kref, struct map_entry, ref));
|
||||||
|
+ remove_entry(container_of(kref, struct map_entry, ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct map_entry *lookup_entry(struct map *map, const void *param)
|
||||||
|
@@ -234,4 +234,4 @@ void *map_get(struct map *map, const void *param)
|
||||||
|
size_t map_size(const struct map *map)
|
||||||
|
{
|
||||||
|
return (map != NULL) ? map->length : 0;
|
||||||
|
-}
|
||||||
|
\ No newline at end of file
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
219
0002-daemon-fix-cannot-get-file-selinux-xattr-when-selinu.patch
Normal file
219
0002-daemon-fix-cannot-get-file-selinux-xattr-when-selinu.patch
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
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
|
||||||
|
|
||||||
385
0003-syscared-fix-syscare-check-command-does-not-check-sy.patch
Normal file
385
0003-syscared-fix-syscare-check-command-does-not-check-sy.patch
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
From e5294afa8135f54f44196bd92e5a32c2b09b9bda Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Wed, 10 Apr 2024 12:19:51 +0800
|
||||||
|
Subject: [PATCH 03/10] syscared: fix 'syscare check command does not check
|
||||||
|
symbol confiliction' issue
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
syscared/src/patch/driver/kpatch/mod.rs | 23 ++-------
|
||||||
|
syscared/src/patch/driver/mod.rs | 66 +++++++++++++++++++------
|
||||||
|
syscared/src/patch/driver/upatch/mod.rs | 35 +++++--------
|
||||||
|
syscared/src/patch/manager.rs | 21 ++++----
|
||||||
|
4 files changed, 79 insertions(+), 66 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/kpatch/mod.rs b/syscared/src/patch/driver/kpatch/mod.rs
|
||||||
|
index e6ab14e..e4509d8 100644
|
||||||
|
--- a/syscared/src/patch/driver/kpatch/mod.rs
|
||||||
|
+++ b/syscared/src/patch/driver/kpatch/mod.rs
|
||||||
|
@@ -24,7 +24,6 @@ use log::debug;
|
||||||
|
use syscare_abi::PatchStatus;
|
||||||
|
use syscare_common::{concat_os, os, util::digest};
|
||||||
|
|
||||||
|
-use super::PatchOpFlag;
|
||||||
|
use crate::patch::entity::KernelPatch;
|
||||||
|
|
||||||
|
mod sys;
|
||||||
|
@@ -103,7 +102,7 @@ impl KernelPatchDriver {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn check_conflict_symbols(&self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
+ pub fn check_conflict_symbols(&self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
let mut conflict_patches = indexset! {};
|
||||||
|
|
||||||
|
let target_symbols = PatchTarget::classify_symbols(&patch.symbols);
|
||||||
|
@@ -132,7 +131,7 @@ impl KernelPatchDriver {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn check_override_symbols(&self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
+ pub fn check_override_symbols(&self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
let mut override_patches = indexset! {};
|
||||||
|
|
||||||
|
let target_symbols = PatchTarget::classify_symbols(&patch.symbols);
|
||||||
|
@@ -196,11 +195,7 @@ impl KernelPatchDriver {
|
||||||
|
sys::read_patch_status(patch)
|
||||||
|
}
|
||||||
|
|
||||||
|
- pub fn check(&self, patch: &KernelPatch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- if flag == PatchOpFlag::Force {
|
||||||
|
- return Ok(());
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ pub fn check(&self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
Self::check_consistency(patch)?;
|
||||||
|
Self::check_compatiblity(patch)?;
|
||||||
|
Self::check_dependency(patch)?;
|
||||||
|
@@ -217,22 +212,14 @@ impl KernelPatchDriver {
|
||||||
|
sys::remove_patch(patch)
|
||||||
|
}
|
||||||
|
|
||||||
|
- pub fn active(&mut self, patch: &KernelPatch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- if flag != PatchOpFlag::Force {
|
||||||
|
- self.check_conflict_symbols(patch)?;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ pub fn active(&mut self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
sys::active_patch(patch)?;
|
||||||
|
self.add_patch_symbols(patch);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- pub fn deactive(&mut self, patch: &KernelPatch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- if flag != PatchOpFlag::Force {
|
||||||
|
- self.check_override_symbols(patch)?;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ pub fn deactive(&mut self, patch: &KernelPatch) -> Result<()> {
|
||||||
|
sys::deactive_patch(patch)?;
|
||||||
|
self.remove_patch_symbols(patch);
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/mod.rs b/syscared/src/patch/driver/mod.rs
|
||||||
|
index 9dff9dd..e6dab94 100644
|
||||||
|
--- a/syscared/src/patch/driver/mod.rs
|
||||||
|
+++ b/syscared/src/patch/driver/mod.rs
|
||||||
|
@@ -36,6 +36,22 @@ pub struct PatchDriver {
|
||||||
|
upatch: UserPatchDriver,
|
||||||
|
}
|
||||||
|
|
||||||
|
+impl PatchDriver {
|
||||||
|
+ fn check_conflict_symbols(&self, patch: &Patch) -> Result<()> {
|
||||||
|
+ match patch {
|
||||||
|
+ Patch::KernelPatch(patch) => self.kpatch.check_conflict_symbols(patch),
|
||||||
|
+ Patch::UserPatch(patch) => self.upatch.check_conflict_symbols(patch),
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fn check_override_symbols(&self, patch: &Patch) -> Result<()> {
|
||||||
|
+ match patch {
|
||||||
|
+ Patch::KernelPatch(patch) => self.kpatch.check_override_symbols(patch),
|
||||||
|
+ Patch::UserPatch(patch) => self.upatch.check_override_symbols(patch),
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
impl PatchDriver {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
info!("Initializing kernel patch driver...");
|
||||||
|
@@ -53,26 +69,40 @@ impl PatchDriver {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetch and return the patch status.
|
||||||
|
- pub fn status(&self, patch: &Patch) -> Result<PatchStatus> {
|
||||||
|
+ pub fn patch_status(&self, patch: &Patch) -> Result<PatchStatus> {
|
||||||
|
match patch {
|
||||||
|
Patch::KernelPatch(patch) => self.kpatch.status(patch),
|
||||||
|
Patch::UserPatch(patch) => self.upatch.status(patch),
|
||||||
|
}
|
||||||
|
+ .with_context(|| format!("Failed to get patch '{}' status", patch))
|
||||||
|
}
|
||||||
|
|
||||||
|
- /// Perform file intergrity & consistency check. </br>
|
||||||
|
- /// Should be used befor patch application.
|
||||||
|
- pub fn check(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ /// Perform patch file intergrity & consistency check. </br>
|
||||||
|
+ /// Should be used before patch application.
|
||||||
|
+ pub fn check_patch(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ if flag == PatchOpFlag::Force {
|
||||||
|
+ return Ok(());
|
||||||
|
+ }
|
||||||
|
match patch {
|
||||||
|
- Patch::KernelPatch(patch) => self.kpatch.check(patch, flag),
|
||||||
|
- Patch::UserPatch(patch) => self.upatch.check(patch, flag),
|
||||||
|
+ Patch::KernelPatch(patch) => self.kpatch.check(patch),
|
||||||
|
+ Patch::UserPatch(patch) => self.upatch.check(patch),
|
||||||
|
+ }
|
||||||
|
+ .with_context(|| format!("Patch '{}' is not patchable", patch))
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /// Perform patch confliction check. </br>
|
||||||
|
+ /// Used for patch check.
|
||||||
|
+ pub fn check_confliction(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ if flag == PatchOpFlag::Force {
|
||||||
|
+ return Ok(());
|
||||||
|
}
|
||||||
|
- .with_context(|| format!("Patch '{}' check failed", patch))
|
||||||
|
+ self.check_conflict_symbols(patch)
|
||||||
|
+ .with_context(|| format!("Patch '{}' is conflicted", patch))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply a patch. </br>
|
||||||
|
/// After this action, the patch status would be changed to 'DEACTIVED'.
|
||||||
|
- pub fn apply(&mut self, patch: &Patch) -> Result<()> {
|
||||||
|
+ pub fn apply_patch(&mut self, patch: &Patch) -> Result<()> {
|
||||||
|
match patch {
|
||||||
|
Patch::KernelPatch(patch) => self.kpatch.apply(patch),
|
||||||
|
Patch::UserPatch(patch) => self.upatch.apply(patch),
|
||||||
|
@@ -82,7 +112,7 @@ impl PatchDriver {
|
||||||
|
|
||||||
|
/// Remove a patch. </br>
|
||||||
|
/// After this action, the patch status would be changed to 'NOT-APPLIED'.
|
||||||
|
- pub fn remove(&mut self, patch: &Patch) -> Result<()> {
|
||||||
|
+ pub fn remove_patch(&mut self, patch: &Patch) -> Result<()> {
|
||||||
|
match patch {
|
||||||
|
Patch::KernelPatch(patch) => self.kpatch.remove(patch),
|
||||||
|
Patch::UserPatch(patch) => self.upatch.remove(patch),
|
||||||
|
@@ -92,20 +122,26 @@ impl PatchDriver {
|
||||||
|
|
||||||
|
/// Active a patch. </br>
|
||||||
|
/// After this action, the patch status would be changed to 'ACTIVED'.
|
||||||
|
- pub fn active(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ pub fn active_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ if flag != PatchOpFlag::Force {
|
||||||
|
+ self.check_conflict_symbols(patch)?;
|
||||||
|
+ }
|
||||||
|
match patch {
|
||||||
|
- Patch::KernelPatch(patch) => self.kpatch.active(patch, flag),
|
||||||
|
- Patch::UserPatch(patch) => self.upatch.active(patch, flag),
|
||||||
|
+ Patch::KernelPatch(patch) => self.kpatch.active(patch),
|
||||||
|
+ Patch::UserPatch(patch) => self.upatch.active(patch),
|
||||||
|
}
|
||||||
|
.with_context(|| format!("Failed to active patch '{}'", patch))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deactive a patch. </br>
|
||||||
|
/// After this action, the patch status would be changed to 'DEACTIVED'.
|
||||||
|
- pub fn deactive(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ pub fn deactive_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ if flag != PatchOpFlag::Force {
|
||||||
|
+ self.check_override_symbols(patch)?;
|
||||||
|
+ }
|
||||||
|
match patch {
|
||||||
|
- Patch::KernelPatch(patch) => self.kpatch.deactive(patch, flag),
|
||||||
|
- Patch::UserPatch(patch) => self.upatch.deactive(patch, flag),
|
||||||
|
+ Patch::KernelPatch(patch) => self.kpatch.deactive(patch),
|
||||||
|
+ Patch::UserPatch(patch) => self.upatch.deactive(patch),
|
||||||
|
}
|
||||||
|
.with_context(|| format!("Failed to deactive patch '{}'", patch))
|
||||||
|
}
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
index 2ca3539..98fc54c 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
@@ -28,7 +28,6 @@ use uuid::Uuid;
|
||||||
|
use syscare_abi::PatchStatus;
|
||||||
|
use syscare_common::util::digest;
|
||||||
|
|
||||||
|
-use super::PatchOpFlag;
|
||||||
|
use crate::patch::entity::UserPatch;
|
||||||
|
|
||||||
|
mod monitor;
|
||||||
|
@@ -71,7 +70,7 @@ impl UserPatchDriver {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserPatchDriver {
|
||||||
|
- fn check_consistency(&self, patch: &UserPatch) -> Result<()> {
|
||||||
|
+ fn check_consistency(patch: &UserPatch) -> Result<()> {
|
||||||
|
let patch_file = patch.patch_file.as_path();
|
||||||
|
let real_checksum = digest::file(patch_file)?;
|
||||||
|
debug!("Target checksum: '{}'", patch.checksum);
|
||||||
|
@@ -84,11 +83,11 @@ impl UserPatchDriver {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn check_compatiblity(&self, _patch: &UserPatch) -> Result<()> {
|
||||||
|
+ fn check_compatiblity(_patch: &UserPatch) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn check_conflict_symbols(&self, patch: &UserPatch) -> Result<()> {
|
||||||
|
+ pub fn check_conflict_symbols(&self, patch: &UserPatch) -> Result<()> {
|
||||||
|
let patch_symbols = patch.symbols.as_slice();
|
||||||
|
let target_name = patch.target_elf.as_os_str();
|
||||||
|
let conflict_patches = match self.patch_target_map.get(target_name) {
|
||||||
|
@@ -114,7 +113,7 @@ impl UserPatchDriver {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn check_override_symbols(&self, patch: &UserPatch) -> Result<()> {
|
||||||
|
+ pub fn check_override_symbols(&self, patch: &UserPatch) -> Result<()> {
|
||||||
|
let patch_uuid = patch.uuid;
|
||||||
|
let patch_symbols = patch.symbols.as_slice();
|
||||||
|
let target_name = patch.target_elf.as_os_str();
|
||||||
|
@@ -233,13 +232,9 @@ impl UserPatchDriver {
|
||||||
|
.unwrap_or(PatchStatus::NotApplied))
|
||||||
|
}
|
||||||
|
|
||||||
|
- pub fn check(&self, patch: &UserPatch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- if flag == PatchOpFlag::Force {
|
||||||
|
- return Ok(());
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- self.check_consistency(patch)?;
|
||||||
|
- self.check_compatiblity(patch)?;
|
||||||
|
+ pub fn check(&self, patch: &UserPatch) -> Result<()> {
|
||||||
|
+ Self::check_consistency(patch)?;
|
||||||
|
+ Self::check_compatiblity(patch)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@@ -272,7 +267,7 @@ impl UserPatchDriver {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- pub fn active(&mut self, patch: &UserPatch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ pub fn active(&mut self, patch: &UserPatch) -> Result<()> {
|
||||||
|
let patch_uuid = patch.uuid;
|
||||||
|
let patch_status = self.get_patch_status(patch_uuid)?;
|
||||||
|
ensure!(
|
||||||
|
@@ -280,10 +275,6 @@ impl UserPatchDriver {
|
||||||
|
"Upatch: Invalid patch status"
|
||||||
|
);
|
||||||
|
|
||||||
|
- if flag != PatchOpFlag::Force {
|
||||||
|
- self.check_conflict_symbols(patch)?;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
let target_elf = patch.target_elf.as_path();
|
||||||
|
let patch_file = patch.patch_file.as_path();
|
||||||
|
let pid_list = process::find_target_process(target_elf)?;
|
||||||
|
@@ -300,13 +291,13 @@ impl UserPatchDriver {
|
||||||
|
|
||||||
|
drop(active_patch_map);
|
||||||
|
|
||||||
|
- self.add_patch_symbols(patch);
|
||||||
|
self.set_patch_status(patch_uuid, PatchStatus::Actived)?;
|
||||||
|
+ self.add_patch_symbols(patch);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
- pub fn deactive(&mut self, patch: &UserPatch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
+ pub fn deactive(&mut self, patch: &UserPatch) -> Result<()> {
|
||||||
|
let patch_uuid = patch.uuid;
|
||||||
|
let patch_status = self.get_patch_status(patch_uuid)?;
|
||||||
|
ensure!(
|
||||||
|
@@ -314,10 +305,6 @@ impl UserPatchDriver {
|
||||||
|
"Upatch: Invalid patch status"
|
||||||
|
);
|
||||||
|
|
||||||
|
- if flag != PatchOpFlag::Force {
|
||||||
|
- self.check_override_symbols(patch)?;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
let target_elf = patch.target_elf.as_path();
|
||||||
|
let patch_file = patch.patch_file.as_path();
|
||||||
|
let pid_list = process::find_target_process(target_elf)?;
|
||||||
|
@@ -337,8 +324,8 @@ impl UserPatchDriver {
|
||||||
|
|
||||||
|
drop(active_patch_map);
|
||||||
|
|
||||||
|
- self.remove_patch_symbols(patch);
|
||||||
|
self.set_patch_status(patch_uuid, PatchStatus::Deactived)?;
|
||||||
|
+ self.remove_patch_symbols(patch);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
diff --git a/syscared/src/patch/manager.rs b/syscared/src/patch/manager.rs
|
||||||
|
index b353bdf..f633567 100644
|
||||||
|
--- a/syscared/src/patch/manager.rs
|
||||||
|
+++ b/syscared/src/patch/manager.rs
|
||||||
|
@@ -134,7 +134,7 @@ impl PatchManager {
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if status == PatchStatus::Unknown {
|
||||||
|
- status = self.driver_get_patch_status(patch, PatchOpFlag::Normal)?;
|
||||||
|
+ status = self.driver_patch_status(patch, PatchOpFlag::Normal)?;
|
||||||
|
self.set_patch_status(patch, status)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -142,7 +142,10 @@ impl PatchManager {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- self.driver_check_patch(patch, flag)
|
||||||
|
+ self.driver.check_patch(patch, flag)?;
|
||||||
|
+ self.driver.check_confliction(patch, flag)?;
|
||||||
|
+
|
||||||
|
+ Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<PatchStatus> {
|
||||||
|
@@ -438,31 +441,31 @@ impl PatchManager {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PatchManager {
|
||||||
|
- fn driver_get_patch_status(&self, patch: &Patch, _flag: PatchOpFlag) -> Result<PatchStatus> {
|
||||||
|
- self.driver.status(patch)
|
||||||
|
+ fn driver_patch_status(&self, patch: &Patch, _flag: PatchOpFlag) -> Result<PatchStatus> {
|
||||||
|
+ self.driver.patch_status(patch)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn driver_check_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- self.driver.check(patch, flag)
|
||||||
|
+ self.driver.check_patch(patch, flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn driver_apply_patch(&mut self, patch: &Patch, _flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- self.driver.apply(patch)?;
|
||||||
|
+ self.driver.apply_patch(patch)?;
|
||||||
|
self.set_patch_status(patch, PatchStatus::Deactived)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn driver_remove_patch(&mut self, patch: &Patch, _flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- self.driver.remove(patch)?;
|
||||||
|
+ self.driver.remove_patch(patch)?;
|
||||||
|
self.set_patch_status(patch, PatchStatus::NotApplied)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn driver_active_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- self.driver.active(patch, flag)?;
|
||||||
|
+ self.driver.active_patch(patch, flag)?;
|
||||||
|
self.set_patch_status(patch, PatchStatus::Actived)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn driver_deactive_patch(&mut self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
|
||||||
|
- self.driver.deactive(patch, flag)?;
|
||||||
|
+ self.driver.deactive_patch(patch, flag)?;
|
||||||
|
self.set_patch_status(patch, PatchStatus::Deactived)
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
687
0004-syscared-fix-cannot-find-process-of-dynlib-patch-iss.patch
Normal file
687
0004-syscared-fix-cannot-find-process-of-dynlib-patch-iss.patch
Normal file
@ -0,0 +1,687 @@
|
|||||||
|
From 32c3d16175b93627504981d05a1a3e3ec603415e Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Wed, 10 Apr 2024 19:30:56 +0800
|
||||||
|
Subject: [PATCH 04/10] syscared: fix 'cannot find process of dynlib patch'
|
||||||
|
issue
|
||||||
|
|
||||||
|
1. For detecting process mapped dynamic library,
|
||||||
|
we use /proc/$pid/map_files instead.
|
||||||
|
We do readlink() to get it's real file path and then
|
||||||
|
read it's inode to judge if it's the file we want.
|
||||||
|
2. For calculating processes to be actived / deactived, we
|
||||||
|
use IndexSet::difference() / IndexSet::intersection() between
|
||||||
|
all current target process and the recorded process set.
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
syscared/src/patch/driver/upatch/mod.rs | 217 ++++++++++++++------
|
||||||
|
syscared/src/patch/driver/upatch/monitor.rs | 18 +-
|
||||||
|
syscared/src/patch/driver/upatch/process.rs | 126 +++++++-----
|
||||||
|
syscared/src/patch/driver/upatch/sys.rs | 108 ++++------
|
||||||
|
4 files changed, 270 insertions(+), 199 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
index 98fc54c..a7fa154 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
@@ -21,7 +21,7 @@ use std::{
|
||||||
|
|
||||||
|
use anyhow::{ensure, Context, Result};
|
||||||
|
use indexmap::{indexset, IndexMap, IndexSet};
|
||||||
|
-use log::{debug, info};
|
||||||
|
+use log::{debug, error};
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@@ -38,31 +38,31 @@ mod target;
|
||||||
|
use monitor::UserPatchMonitor;
|
||||||
|
use target::PatchTarget;
|
||||||
|
|
||||||
|
-pub(self) type ActivePatchMap = Arc<Mutex<IndexMap<PathBuf, ActivePatch>>>;
|
||||||
|
+type ElfPatchMap = Arc<Mutex<IndexMap<PathBuf, ElfPatchRecord>>>;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
-struct ActivePatch {
|
||||||
|
- patch_list: Vec<(Uuid, PathBuf)>, // Patch applied to target elf (uuid and patch file)
|
||||||
|
- process_list: IndexSet<i32>, // Target elf process list
|
||||||
|
+struct ElfPatchRecord {
|
||||||
|
+ patch_map: IndexMap<Uuid, PathBuf>, // Patch applied to target elf (uuid and patch file)
|
||||||
|
+ processes: IndexSet<i32>, // Target elf process list
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UserPatchDriver {
|
||||||
|
patch_target_map: IndexMap<OsString, PatchTarget>,
|
||||||
|
patch_status_map: IndexMap<Uuid, PatchStatus>,
|
||||||
|
- active_patch_map: ActivePatchMap,
|
||||||
|
+ elf_patch_map: ElfPatchMap,
|
||||||
|
patch_monitor: UserPatchMonitor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserPatchDriver {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
- let active_patch_map = Arc::new(Mutex::new(IndexMap::new()));
|
||||||
|
+ let elf_patch_map = Arc::new(Mutex::new(IndexMap::new()));
|
||||||
|
let patch_monitor =
|
||||||
|
- UserPatchMonitor::new(active_patch_map.clone(), Self::on_new_process_created)?;
|
||||||
|
+ UserPatchMonitor::new(elf_patch_map.clone(), Self::patch_new_process)?;
|
||||||
|
|
||||||
|
let instance = Self {
|
||||||
|
patch_target_map: IndexMap::new(),
|
||||||
|
patch_status_map: IndexMap::new(),
|
||||||
|
- active_patch_map,
|
||||||
|
+ elf_patch_map,
|
||||||
|
patch_monitor,
|
||||||
|
};
|
||||||
|
Ok(instance)
|
||||||
|
@@ -168,36 +168,51 @@ impl UserPatchDriver {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserPatchDriver {
|
||||||
|
- fn on_new_process_created(active_patch_map: ActivePatchMap, target_elf: &Path) -> Result<()> {
|
||||||
|
- // find actived patch
|
||||||
|
- if let Some(patch_record) = active_patch_map.lock().get_mut(target_elf) {
|
||||||
|
- let current_process_list = process::find_target_process(target_elf)?;
|
||||||
|
- let patched_process_list = &patch_record.process_list;
|
||||||
|
-
|
||||||
|
- // Filter patched pid
|
||||||
|
- let pid_list = current_process_list
|
||||||
|
- .iter()
|
||||||
|
- .filter(|pid| !patched_process_list.contains(*pid))
|
||||||
|
- .copied()
|
||||||
|
- .collect::<Vec<_>>();
|
||||||
|
- if pid_list.is_empty() {
|
||||||
|
- return Ok(());
|
||||||
|
- }
|
||||||
|
+ fn patch_new_process(elf_patch_map: ElfPatchMap, target_elf: &Path) {
|
||||||
|
+ let process_list = match process::find_target_process(target_elf) {
|
||||||
|
+ Ok(processes) => processes,
|
||||||
|
+ Err(_) => return,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ let mut patch_map = elf_patch_map.lock();
|
||||||
|
+ let patch_record = match patch_map.get_mut(target_elf) {
|
||||||
|
+ Some(record) => record,
|
||||||
|
+ None => return,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ let need_active = process_list
|
||||||
|
+ .difference(&patch_record.processes)
|
||||||
|
+ .copied()
|
||||||
|
+ .collect::<Vec<_>>();
|
||||||
|
|
||||||
|
- for (uuid, patch_file) in &patch_record.patch_list {
|
||||||
|
- info!(
|
||||||
|
- "Patching '{}' ({}) to process {:?}",
|
||||||
|
+ // Active patch
|
||||||
|
+ for (uuid, patch_file) in &patch_record.patch_map {
|
||||||
|
+ if !need_active.is_empty() {
|
||||||
|
+ debug!(
|
||||||
|
+ "Upatch: Activating patch '{}' ({}) to process {:?}",
|
||||||
|
uuid,
|
||||||
|
target_elf.display(),
|
||||||
|
- pid_list,
|
||||||
|
+ need_active,
|
||||||
|
);
|
||||||
|
- sys::active_patch(uuid, target_elf, patch_file, &pid_list)?;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- patch_record.process_list = current_process_list;
|
||||||
|
+ for pid in &need_active {
|
||||||
|
+ if let Err(e) = sys::active_patch(uuid, *pid, target_elf, patch_file) {
|
||||||
|
+ error!("{:?}", e);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ patch_record.processes.insert(*pid);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- Ok(())
|
||||||
|
+ // Remove process no longer exists
|
||||||
|
+ let need_remove = patch_record
|
||||||
|
+ .processes
|
||||||
|
+ .difference(&process_list)
|
||||||
|
+ .copied()
|
||||||
|
+ .collect::<Vec<_>>();
|
||||||
|
+ for pid in need_remove {
|
||||||
|
+ patch_record.processes.remove(&pid);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -246,7 +261,11 @@ impl UserPatchDriver {
|
||||||
|
"Upatch: Patch already exists"
|
||||||
|
);
|
||||||
|
|
||||||
|
- debug!("Upatch: Applying patch '{}'", patch_uuid);
|
||||||
|
+ debug!(
|
||||||
|
+ "Upatch: Applying patch '{}', patch_file: {}",
|
||||||
|
+ patch_uuid,
|
||||||
|
+ patch.patch_file.display()
|
||||||
|
+ );
|
||||||
|
self.patch_status_map
|
||||||
|
.insert(patch_uuid, PatchStatus::Deactived);
|
||||||
|
|
||||||
|
@@ -261,15 +280,19 @@ impl UserPatchDriver {
|
||||||
|
"Upatch: Invalid patch status"
|
||||||
|
);
|
||||||
|
|
||||||
|
- debug!("Upatch: Removing patch '{}'", patch_uuid);
|
||||||
|
+ debug!(
|
||||||
|
+ "Upatch: Removing patch '{}', patch_file: {}",
|
||||||
|
+ patch_uuid,
|
||||||
|
+ patch.patch_file.display()
|
||||||
|
+ );
|
||||||
|
self.patch_status_map.remove(&patch_uuid);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn active(&mut self, patch: &UserPatch) -> Result<()> {
|
||||||
|
- let patch_uuid = patch.uuid;
|
||||||
|
- let patch_status = self.get_patch_status(patch_uuid)?;
|
||||||
|
+ let uuid = patch.uuid;
|
||||||
|
+ let patch_status = self.get_patch_status(uuid)?;
|
||||||
|
ensure!(
|
||||||
|
patch_status == PatchStatus::Deactived,
|
||||||
|
"Upatch: Invalid patch status"
|
||||||
|
@@ -277,29 +300,65 @@ impl UserPatchDriver {
|
||||||
|
|
||||||
|
let target_elf = patch.target_elf.as_path();
|
||||||
|
let patch_file = patch.patch_file.as_path();
|
||||||
|
- let pid_list = process::find_target_process(target_elf)?;
|
||||||
|
- sys::active_patch(&patch_uuid, target_elf, patch_file, &pid_list)?;
|
||||||
|
+ let process_list = process::find_target_process(target_elf)?;
|
||||||
|
+
|
||||||
|
+ let mut patch_map = self.elf_patch_map.lock();
|
||||||
|
+ let patch_record = patch_map.entry(target_elf.to_path_buf()).or_default();
|
||||||
|
+
|
||||||
|
+ let need_active = process_list
|
||||||
|
+ .difference(&patch_record.processes)
|
||||||
|
+ .copied()
|
||||||
|
+ .collect::<Vec<_>>();
|
||||||
|
+ let need_remove = patch_record
|
||||||
|
+ .processes
|
||||||
|
+ .difference(&process_list)
|
||||||
|
+ .copied()
|
||||||
|
+ .collect::<Vec<_>>();
|
||||||
|
+ let mut need_start_watch = false;
|
||||||
|
+
|
||||||
|
+ // Active patch
|
||||||
|
+ if !need_active.is_empty() {
|
||||||
|
+ debug!(
|
||||||
|
+ "Upatch: Activating patch '{}' ({}) to process {:?}",
|
||||||
|
+ uuid,
|
||||||
|
+ target_elf.display(),
|
||||||
|
+ need_active,
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+ for pid in need_active {
|
||||||
|
+ if let Err(e) = sys::active_patch(&uuid, pid, target_elf, patch_file) {
|
||||||
|
+ error!("{:?}", e);
|
||||||
|
+ }
|
||||||
|
+ patch_record.processes.insert(pid);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- let mut active_patch_map = self.active_patch_map.lock();
|
||||||
|
- let active_patch = active_patch_map
|
||||||
|
- .entry(target_elf.to_path_buf())
|
||||||
|
- .or_default();
|
||||||
|
- let patch_list = &mut active_patch.patch_list;
|
||||||
|
+ // Remove process no longer exists
|
||||||
|
+ for pid in need_remove {
|
||||||
|
+ patch_record.processes.remove(&pid);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- patch_list.push((patch_uuid, patch_file.to_path_buf()));
|
||||||
|
- self.patch_monitor.watch_file(target_elf)?;
|
||||||
|
+ // If elf is not patched before, start watching it & add a new entry
|
||||||
|
+ if !patch_record.patch_map.contains_key(&uuid) {
|
||||||
|
+ patch_record
|
||||||
|
+ .patch_map
|
||||||
|
+ .insert(uuid, patch_file.to_path_buf());
|
||||||
|
+ need_start_watch = true;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- drop(active_patch_map);
|
||||||
|
+ drop(patch_map);
|
||||||
|
|
||||||
|
- self.set_patch_status(patch_uuid, PatchStatus::Actived)?;
|
||||||
|
+ if need_start_watch {
|
||||||
|
+ self.patch_monitor.watch_file(target_elf)?;
|
||||||
|
+ }
|
||||||
|
+ self.set_patch_status(uuid, PatchStatus::Actived)?;
|
||||||
|
self.add_patch_symbols(patch);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deactive(&mut self, patch: &UserPatch) -> Result<()> {
|
||||||
|
- let patch_uuid = patch.uuid;
|
||||||
|
- let patch_status = self.get_patch_status(patch_uuid)?;
|
||||||
|
+ let uuid = patch.uuid;
|
||||||
|
+ let patch_status = self.get_patch_status(uuid)?;
|
||||||
|
ensure!(
|
||||||
|
patch_status == PatchStatus::Actived,
|
||||||
|
"Upatch: Invalid patch status"
|
||||||
|
@@ -307,24 +366,58 @@ impl UserPatchDriver {
|
||||||
|
|
||||||
|
let target_elf = patch.target_elf.as_path();
|
||||||
|
let patch_file = patch.patch_file.as_path();
|
||||||
|
- let pid_list = process::find_target_process(target_elf)?;
|
||||||
|
- sys::deactive_patch(&patch_uuid, target_elf, patch_file, &pid_list)?;
|
||||||
|
+ let process_list = process::find_target_process(target_elf)?;
|
||||||
|
|
||||||
|
- let mut active_patch_map = self.active_patch_map.lock();
|
||||||
|
- let active_patch = active_patch_map
|
||||||
|
- .entry(target_elf.to_path_buf())
|
||||||
|
- .or_default();
|
||||||
|
- let patch_list = &mut active_patch.patch_list;
|
||||||
|
+ let mut patch_map = self.elf_patch_map.lock();
|
||||||
|
+ let patch_record = patch_map
|
||||||
|
+ .get_mut(target_elf)
|
||||||
|
+ .context("Failed to find elf patch record")?;
|
||||||
|
|
||||||
|
- patch_list.pop();
|
||||||
|
- if patch_list.is_empty() {
|
||||||
|
- self.patch_monitor.ignore_file(target_elf)?;
|
||||||
|
- active_patch_map.remove(target_elf);
|
||||||
|
+ let need_deactive = process_list
|
||||||
|
+ .intersection(&patch_record.processes)
|
||||||
|
+ .copied()
|
||||||
|
+ .collect::<Vec<_>>();
|
||||||
|
+ let need_removed = patch_record
|
||||||
|
+ .processes
|
||||||
|
+ .difference(&process_list)
|
||||||
|
+ .copied()
|
||||||
|
+ .collect::<Vec<_>>();
|
||||||
|
+ let mut need_stop_watch = false;
|
||||||
|
+
|
||||||
|
+ // Deactive patch
|
||||||
|
+ if !need_deactive.is_empty() {
|
||||||
|
+ debug!(
|
||||||
|
+ "Upatch: Deactivating patch '{}' ({}) of process {:?}",
|
||||||
|
+ uuid,
|
||||||
|
+ target_elf.display(),
|
||||||
|
+ need_deactive,
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+ for pid in need_deactive {
|
||||||
|
+ sys::deactive_patch(&uuid, pid, target_elf, patch_file)?;
|
||||||
|
+ patch_record.processes.remove(&pid); // remove process from record
|
||||||
|
}
|
||||||
|
|
||||||
|
- drop(active_patch_map);
|
||||||
|
+ // Remove process no longer exists
|
||||||
|
+ for pid in need_removed {
|
||||||
|
+ patch_record.processes.remove(&pid);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- self.set_patch_status(patch_uuid, PatchStatus::Deactived)?;
|
||||||
|
+ // Remove patch from elf patch record
|
||||||
|
+ patch_record.patch_map.remove(&uuid);
|
||||||
|
+
|
||||||
|
+ // If elf has no more patch, stop watching it & remove the entry
|
||||||
|
+ if patch_record.patch_map.is_empty() {
|
||||||
|
+ patch_map.remove(target_elf);
|
||||||
|
+ need_stop_watch = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ drop(patch_map);
|
||||||
|
+
|
||||||
|
+ if need_stop_watch {
|
||||||
|
+ self.patch_monitor.ignore_file(target_elf)?;
|
||||||
|
+ }
|
||||||
|
+ self.set_patch_status(uuid, PatchStatus::Deactived)?;
|
||||||
|
self.remove_patch_symbols(patch);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/monitor.rs b/syscared/src/patch/driver/upatch/monitor.rs
|
||||||
|
index 0dd4088..1dbb513 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/monitor.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/monitor.rs
|
||||||
|
@@ -23,10 +23,10 @@ use std::{
|
||||||
|
use anyhow::{bail, Context, Result};
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
use inotify::{EventMask, Inotify, WatchDescriptor, WatchMask};
|
||||||
|
-use log::{error, info};
|
||||||
|
+use log::info;
|
||||||
|
use parking_lot::{Mutex, RwLock};
|
||||||
|
|
||||||
|
-use super::ActivePatchMap;
|
||||||
|
+use super::ElfPatchMap;
|
||||||
|
|
||||||
|
const MONITOR_THREAD_NAME: &str = "upatch_monitor";
|
||||||
|
const MONITOR_CHECK_PERIOD: u64 = 100;
|
||||||
|
@@ -40,9 +40,9 @@ pub(super) struct UserPatchMonitor {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserPatchMonitor {
|
||||||
|
- pub fn new<F>(active_patch_map: ActivePatchMap, callback: F) -> Result<Self>
|
||||||
|
+ pub fn new<F>(elf_patch_map: ElfPatchMap, callback: F) -> Result<Self>
|
||||||
|
where
|
||||||
|
- F: Fn(ActivePatchMap, &Path) -> Result<()> + Send + 'static,
|
||||||
|
+ F: Fn(ElfPatchMap, &Path) + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let inotify = Arc::new(Mutex::new(Some(
|
||||||
|
Inotify::init().context("Failed to initialize inotify")?,
|
||||||
|
@@ -52,7 +52,7 @@ impl UserPatchMonitor {
|
||||||
|
let monitor_thread = MonitorThread {
|
||||||
|
inotify: inotify.clone(),
|
||||||
|
target_map: target_map.clone(),
|
||||||
|
- active_patch_map,
|
||||||
|
+ elf_patch_map,
|
||||||
|
callback,
|
||||||
|
}
|
||||||
|
.run()?;
|
||||||
|
@@ -115,13 +115,13 @@ impl UserPatchMonitor {
|
||||||
|
struct MonitorThread<F> {
|
||||||
|
inotify: Arc<Mutex<Option<Inotify>>>,
|
||||||
|
target_map: Arc<RwLock<IndexMap<WatchDescriptor, PathBuf>>>,
|
||||||
|
- active_patch_map: ActivePatchMap,
|
||||||
|
+ elf_patch_map: ElfPatchMap,
|
||||||
|
callback: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F> MonitorThread<F>
|
||||||
|
where
|
||||||
|
- F: Fn(ActivePatchMap, &Path) -> Result<()> + Send + 'static,
|
||||||
|
+ F: Fn(ElfPatchMap, &Path) + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
fn run(self) -> Result<thread::JoinHandle<()>> {
|
||||||
|
thread::Builder::new()
|
||||||
|
@@ -140,9 +140,7 @@ where
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(patch_file) = self.target_map.read().get(&event.wd) {
|
||||||
|
- if let Err(e) = (self.callback)(self.active_patch_map.clone(), patch_file) {
|
||||||
|
- error!("{:?}", e);
|
||||||
|
- }
|
||||||
|
+ (self.callback)(self.elf_patch_map.clone(), patch_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/process.rs b/syscared/src/patch/driver/upatch/process.rs
|
||||||
|
index 597fc0e..9b2f6de 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/process.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/process.rs
|
||||||
|
@@ -12,77 +12,89 @@
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-use std::{
|
||||||
|
- ffi::OsStr,
|
||||||
|
- path::{Path, PathBuf},
|
||||||
|
-};
|
||||||
|
+use std::{ffi::OsStr, os::linux::fs::MetadataExt, path::Path};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use indexmap::IndexSet;
|
||||||
|
use syscare_common::fs;
|
||||||
|
|
||||||
|
-use syscare_common::os::proc_maps::ProcMaps;
|
||||||
|
+const PROC_BLACK_LIST: [&str; 18] = [
|
||||||
|
+ "/usr/lib/systemd/systemd-journald",
|
||||||
|
+ "/usr/lib/systemd/systemd-logind",
|
||||||
|
+ "/usr/lib/systemd/systemd-udevd",
|
||||||
|
+ "/usr/lib/systemd/systemd-hostnamed",
|
||||||
|
+ "/usr/bin/udevadm",
|
||||||
|
+ "/usr/sbin/auditd",
|
||||||
|
+ "/usr/bin/syscare",
|
||||||
|
+ "/usr/bin/syscared",
|
||||||
|
+ "/usr/bin/upatchd",
|
||||||
|
+ "/usr/libexec/syscare/as-hijacker",
|
||||||
|
+ "/usr/libexec/syscare/cc-hijacker",
|
||||||
|
+ "/usr/libexec/syscare/c++-hijacker",
|
||||||
|
+ "/usr/libexec/syscare/gcc-hijacker",
|
||||||
|
+ "/usr/libexec/syscare/g++-hijacker",
|
||||||
|
+ "/usr/libexec/syscare/syscare-build",
|
||||||
|
+ "/usr/libexec/syscare/upatch-build",
|
||||||
|
+ "/usr/libexec/syscare/upatch-diff",
|
||||||
|
+ "/usr/libexec/syscare/upatch-manage",
|
||||||
|
+];
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
-fn parse_process_id<P: AsRef<Path>>(path: P) -> Option<i32> {
|
||||||
|
- path.as_ref()
|
||||||
|
+fn is_blacklisted(file_path: &Path) -> bool {
|
||||||
|
+ PROC_BLACK_LIST
|
||||||
|
+ .iter()
|
||||||
|
+ .map(Path::new)
|
||||||
|
+ .any(|blacklist_path| blacklist_path == file_path)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#[inline]
|
||||||
|
+fn parse_process_id(proc_path: &Path) -> Option<i32> {
|
||||||
|
+ proc_path
|
||||||
|
.file_name()
|
||||||
|
.and_then(OsStr::to_str)
|
||||||
|
.map(str::parse)
|
||||||
|
.and_then(Result::ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
-#[inline]
|
||||||
|
-fn parse_process_path(pid: i32) -> Option<(i32, PathBuf)> {
|
||||||
|
- const PROC_BLACK_LIST: [&str; 18] = [
|
||||||
|
- "/usr/lib/systemd/systemd-journald",
|
||||||
|
- "/usr/lib/systemd/systemd-logind",
|
||||||
|
- "/usr/lib/systemd/systemd-udevd",
|
||||||
|
- "/usr/lib/systemd/systemd-hostnamed",
|
||||||
|
- "/usr/bin/udevadm",
|
||||||
|
- "/usr/sbin/auditd",
|
||||||
|
- "/usr/bin/syscare",
|
||||||
|
- "/usr/bin/syscared",
|
||||||
|
- "/usr/bin/upatchd",
|
||||||
|
- "/usr/libexec/syscare/as-hijacker",
|
||||||
|
- "/usr/libexec/syscare/cc-hijacker",
|
||||||
|
- "/usr/libexec/syscare/c++-hijacker",
|
||||||
|
- "/usr/libexec/syscare/gcc-hijacker",
|
||||||
|
- "/usr/libexec/syscare/g++-hijacker",
|
||||||
|
- "/usr/libexec/syscare/syscare-build",
|
||||||
|
- "/usr/libexec/syscare/upatch-build",
|
||||||
|
- "/usr/libexec/syscare/upatch-diff",
|
||||||
|
- "/usr/libexec/syscare/upatch-manage",
|
||||||
|
- ];
|
||||||
|
-
|
||||||
|
- fs::read_link(format!("/proc/{}/exe", pid))
|
||||||
|
- .ok()
|
||||||
|
- .filter(|path| {
|
||||||
|
- !PROC_BLACK_LIST
|
||||||
|
- .iter()
|
||||||
|
- .any(|blacklist_path| path.as_os_str() == *blacklist_path)
|
||||||
|
- })
|
||||||
|
- .map(|path| (pid, path))
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
pub fn find_target_process<P: AsRef<Path>>(target_elf: P) -> Result<IndexSet<i32>> {
|
||||||
|
- let target_file = fs::canonicalize(target_elf.as_ref())?;
|
||||||
|
- let target_path = target_file.as_path();
|
||||||
|
- let target_pids = fs::list_dirs("/proc", fs::TraverseOptions { recursive: false })?
|
||||||
|
- .into_iter()
|
||||||
|
- .filter_map(self::parse_process_id)
|
||||||
|
- .filter_map(self::parse_process_path)
|
||||||
|
- .filter(|(pid, bin_path)| {
|
||||||
|
- if bin_path == target_path {
|
||||||
|
- return true;
|
||||||
|
- }
|
||||||
|
- if let Ok(mut mappings) = ProcMaps::new(*pid) {
|
||||||
|
- return mappings.any(|map| map.path_name == target_path);
|
||||||
|
- }
|
||||||
|
- false
|
||||||
|
- })
|
||||||
|
- .map(|(pid, _)| pid)
|
||||||
|
- .collect();
|
||||||
|
+ let mut target_pids = IndexSet::new();
|
||||||
|
+ let target_path = target_elf.as_ref();
|
||||||
|
+ let target_inode = target_path.metadata()?.st_ino();
|
||||||
|
+
|
||||||
|
+ for proc_path in fs::list_dirs("/proc", fs::TraverseOptions { recursive: false })? {
|
||||||
|
+ let pid = match self::parse_process_id(&proc_path) {
|
||||||
|
+ Some(pid) => pid,
|
||||||
|
+ None => continue,
|
||||||
|
+ };
|
||||||
|
+ let exec_path = match fs::read_link(format!("/proc/{}/exe", pid)) {
|
||||||
|
+ Ok(file_path) => file_path,
|
||||||
|
+ Err(_) => continue,
|
||||||
|
+ };
|
||||||
|
+ if is_blacklisted(&exec_path) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ // Try to match binary path
|
||||||
|
+ if exec_path == target_path {
|
||||||
|
+ target_pids.insert(pid);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ // Try to match mapped files
|
||||||
|
+ let map_files = fs::list_symlinks(
|
||||||
|
+ format!("/proc/{}/map_files", pid),
|
||||||
|
+ fs::TraverseOptions { recursive: false },
|
||||||
|
+ )?;
|
||||||
|
+ for mapped_file in map_files {
|
||||||
|
+ if let Ok(mapped_inode) = mapped_file
|
||||||
|
+ .read_link()
|
||||||
|
+ .and_then(|file_path| Ok(file_path.metadata()?.st_ino()))
|
||||||
|
+ {
|
||||||
|
+ if mapped_inode == target_inode {
|
||||||
|
+ target_pids.insert(pid);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Ok(target_pids)
|
||||||
|
}
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
index bab2974..f0745f0 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
-use log::{debug, Level};
|
||||||
|
+use log::Level;
|
||||||
|
use nix::libc::EEXIST;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@@ -9,80 +9,48 @@ use syscare_common::process::Command;
|
||||||
|
|
||||||
|
const UPATCH_MANAGE_BIN: &str = "/usr/libexec/syscare/upatch-manage";
|
||||||
|
|
||||||
|
-pub fn active_patch<'a, I>(
|
||||||
|
- uuid: &Uuid,
|
||||||
|
- target_elf: &Path,
|
||||||
|
- patch_file: &Path,
|
||||||
|
- pid_list: I,
|
||||||
|
-) -> Result<()>
|
||||||
|
-where
|
||||||
|
- I: IntoIterator<Item = &'a i32>,
|
||||||
|
-{
|
||||||
|
- debug!(
|
||||||
|
- "Patching '{}' to {}",
|
||||||
|
- patch_file.display(),
|
||||||
|
- target_elf.display()
|
||||||
|
- );
|
||||||
|
-
|
||||||
|
- for pid in pid_list {
|
||||||
|
- let exit_code = Command::new(UPATCH_MANAGE_BIN)
|
||||||
|
- .arg("patch")
|
||||||
|
- .arg("--uuid")
|
||||||
|
- .arg(uuid.to_string())
|
||||||
|
- .arg("--pid")
|
||||||
|
- .arg(pid.to_string())
|
||||||
|
- .arg("--binary")
|
||||||
|
- .arg(target_elf)
|
||||||
|
- .arg("--upatch")
|
||||||
|
- .arg(patch_file)
|
||||||
|
- .stdout(Level::Debug)
|
||||||
|
- .run_with_output()?
|
||||||
|
- .exit_code();
|
||||||
|
-
|
||||||
|
- match exit_code {
|
||||||
|
- 0 => {}
|
||||||
|
- EEXIST => {}
|
||||||
|
- _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
|
||||||
|
- }
|
||||||
|
+pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path) -> Result<()> {
|
||||||
|
+ let exit_code = Command::new(UPATCH_MANAGE_BIN)
|
||||||
|
+ .arg("patch")
|
||||||
|
+ .arg("--uuid")
|
||||||
|
+ .arg(uuid.to_string())
|
||||||
|
+ .arg("--pid")
|
||||||
|
+ .arg(pid.to_string())
|
||||||
|
+ .arg("--binary")
|
||||||
|
+ .arg(target_elf)
|
||||||
|
+ .arg("--upatch")
|
||||||
|
+ .arg(patch_file)
|
||||||
|
+ .stdout(Level::Debug)
|
||||||
|
+ .run_with_output()?
|
||||||
|
+ .exit_code();
|
||||||
|
+
|
||||||
|
+ match exit_code {
|
||||||
|
+ 0 => {}
|
||||||
|
+ EEXIST => {}
|
||||||
|
+ _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
-pub fn deactive_patch<'a, I>(
|
||||||
|
- uuid: &Uuid,
|
||||||
|
- target_elf: &Path,
|
||||||
|
- patch_file: &Path,
|
||||||
|
- pid_list: I,
|
||||||
|
-) -> Result<()>
|
||||||
|
-where
|
||||||
|
- I: IntoIterator<Item = &'a i32>,
|
||||||
|
-{
|
||||||
|
- debug!(
|
||||||
|
- "Unpatching '{}' from {}",
|
||||||
|
- patch_file.display(),
|
||||||
|
- target_elf.display()
|
||||||
|
- );
|
||||||
|
-
|
||||||
|
- for pid in pid_list {
|
||||||
|
- let exit_code = Command::new(UPATCH_MANAGE_BIN)
|
||||||
|
- .arg("unpatch")
|
||||||
|
- .arg("--uuid")
|
||||||
|
- .arg(uuid.to_string())
|
||||||
|
- .arg("--pid")
|
||||||
|
- .arg(pid.to_string())
|
||||||
|
- .arg("--binary")
|
||||||
|
- .arg(target_elf)
|
||||||
|
- .arg("--upatch")
|
||||||
|
- .arg(patch_file)
|
||||||
|
- .stdout(Level::Debug)
|
||||||
|
- .run_with_output()?
|
||||||
|
- .exit_code();
|
||||||
|
-
|
||||||
|
- match exit_code {
|
||||||
|
- 0 => {}
|
||||||
|
- _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
|
||||||
|
- }
|
||||||
|
+pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path) -> Result<()> {
|
||||||
|
+ let exit_code = Command::new(UPATCH_MANAGE_BIN)
|
||||||
|
+ .arg("unpatch")
|
||||||
|
+ .arg("--uuid")
|
||||||
|
+ .arg(uuid.to_string())
|
||||||
|
+ .arg("--pid")
|
||||||
|
+ .arg(pid.to_string())
|
||||||
|
+ .arg("--binary")
|
||||||
|
+ .arg(target_elf)
|
||||||
|
+ .arg("--upatch")
|
||||||
|
+ .arg(patch_file)
|
||||||
|
+ .stdout(Level::Debug)
|
||||||
|
+ .run_with_output()?
|
||||||
|
+ .exit_code();
|
||||||
|
+
|
||||||
|
+ match exit_code {
|
||||||
|
+ 0 => {}
|
||||||
|
+ _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
222
0005-abi-change-uuid-type-from-string-to-uuid-bytes.patch
Normal file
222
0005-abi-change-uuid-type-from-string-to-uuid-bytes.patch
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
From c213504c02d73738a86935fb5883f2e59d083da7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ningyu <ningyu9@huawei.com>
|
||||||
|
Date: Tue, 9 Apr 2024 09:21:35 +0000
|
||||||
|
Subject: [PATCH 05/10] abi: change uuid type from string to uuid bytes
|
||||||
|
|
||||||
|
---
|
||||||
|
Cargo.lock | 1 +
|
||||||
|
syscare-abi/Cargo.toml | 1 +
|
||||||
|
syscare-abi/src/patch_info.rs | 6 ++++--
|
||||||
|
syscare-build/src/package/rpm/spec_builder.rs | 4 ++--
|
||||||
|
syscare-build/src/patch/kernel_patch/kpatch_builder.rs | 6 +++---
|
||||||
|
syscare-build/src/patch/metadata.rs | 4 +++-
|
||||||
|
syscare-build/src/patch/user_patch/upatch_builder.rs | 4 ++--
|
||||||
|
syscared/src/patch/resolver/kpatch.rs | 4 +---
|
||||||
|
syscared/src/patch/resolver/upatch.rs | 5 ++---
|
||||||
|
9 files changed, 19 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index 1d13df6..e6d830b 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -1129,6 +1129,7 @@ name = "syscare-abi"
|
||||||
|
version = "1.2.1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
+ "uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
diff --git a/syscare-abi/Cargo.toml b/syscare-abi/Cargo.toml
|
||||||
|
index 7b23a8a..f086850 100644
|
||||||
|
--- a/syscare-abi/Cargo.toml
|
||||||
|
+++ b/syscare-abi/Cargo.toml
|
||||||
|
@@ -10,3 +10,4 @@ build = "build.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
+uuid = { version = "0.8", features = ["v4"] }
|
||||||
|
diff --git a/syscare-abi/src/patch_info.rs b/syscare-abi/src/patch_info.rs
|
||||||
|
index 55618ae..08cc2c7 100644
|
||||||
|
--- a/syscare-abi/src/patch_info.rs
|
||||||
|
+++ b/syscare-abi/src/patch_info.rs
|
||||||
|
@@ -16,6 +16,8 @@ use std::{ffi::OsString, path::PathBuf};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
+use uuid::Uuid;
|
||||||
|
+
|
||||||
|
use super::package_info::PackageInfo;
|
||||||
|
|
||||||
|
pub const PATCH_INFO_MAGIC: &str = "112574B6EDEE4BA4A05F";
|
||||||
|
@@ -34,7 +36,7 @@ impl std::fmt::Display for PatchType {
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct PatchEntity {
|
||||||
|
- pub uuid: String,
|
||||||
|
+ pub uuid: Uuid,
|
||||||
|
pub patch_name: OsString,
|
||||||
|
pub patch_target: PathBuf,
|
||||||
|
pub checksum: String,
|
||||||
|
@@ -49,7 +51,7 @@ pub struct PatchFile {
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct PatchInfo {
|
||||||
|
- pub uuid: String,
|
||||||
|
+ pub uuid: Uuid,
|
||||||
|
pub name: String,
|
||||||
|
pub version: String,
|
||||||
|
pub release: u32,
|
||||||
|
diff --git a/syscare-build/src/package/rpm/spec_builder.rs b/syscare-build/src/package/rpm/spec_builder.rs
|
||||||
|
index 88f57d8..a24954f 100644
|
||||||
|
--- a/syscare-build/src/package/rpm/spec_builder.rs
|
||||||
|
+++ b/syscare-build/src/package/rpm/spec_builder.rs
|
||||||
|
@@ -62,7 +62,7 @@ impl RpmSpecBuilder {
|
||||||
|
fn parse_patch_uuid(patch_info: &PatchInfo) -> String {
|
||||||
|
let mut result = String::new();
|
||||||
|
for entity in &patch_info.entities {
|
||||||
|
- result.push_str(&entity.uuid);
|
||||||
|
+ result.push_str(&entity.uuid.to_string());
|
||||||
|
result.push(' ');
|
||||||
|
}
|
||||||
|
result = result.trim().to_string();
|
||||||
|
@@ -113,7 +113,7 @@ impl RpmSpecBuilder {
|
||||||
|
patch_info.name
|
||||||
|
);
|
||||||
|
let pkg_version = format!("{}-{}", patch_info.version, patch_info.release);
|
||||||
|
- let pkg_root = Path::new(PKG_INSTALL_DIR).join(&patch_info.uuid);
|
||||||
|
+ let pkg_root = Path::new(PKG_INSTALL_DIR).join(patch_info.uuid.to_string());
|
||||||
|
|
||||||
|
let mut spec = RpmSpecFile::new(
|
||||||
|
pkg_name,
|
||||||
|
diff --git a/syscare-build/src/patch/kernel_patch/kpatch_builder.rs b/syscare-build/src/patch/kernel_patch/kpatch_builder.rs
|
||||||
|
index 1b66510..ba49661 100644
|
||||||
|
--- a/syscare-build/src/patch/kernel_patch/kpatch_builder.rs
|
||||||
|
+++ b/syscare-build/src/patch/kernel_patch/kpatch_builder.rs
|
||||||
|
@@ -150,7 +150,7 @@ impl KernelPatchBuilder {
|
||||||
|
match &kbuild_params.oot_source_dir {
|
||||||
|
// Kernel patch
|
||||||
|
None => {
|
||||||
|
- let entity_uuid = Uuid::new_v4().to_string();
|
||||||
|
+ let entity_uuid = Uuid::new_v4();
|
||||||
|
let entity_target = VMLINUX_FILE_NAME;
|
||||||
|
let entity_name = format!("{}-{}", entity_target, entity_uuid);
|
||||||
|
|
||||||
|
@@ -182,7 +182,7 @@ impl KernelPatchBuilder {
|
||||||
|
.to_string_lossy()
|
||||||
|
.replace(['.', '-'], "_");
|
||||||
|
|
||||||
|
- let entity_uuid: String = Uuid::new_v4().to_string();
|
||||||
|
+ let entity_uuid = Uuid::new_v4();
|
||||||
|
let entitiy_name = format!("{}-{}", module_name, entity_uuid);
|
||||||
|
let entity_target = file_name.to_os_string();
|
||||||
|
|
||||||
|
@@ -290,7 +290,7 @@ impl KernelPatchBuilder {
|
||||||
|
) -> Result<Vec<PatchInfo>> {
|
||||||
|
// Generate patch info
|
||||||
|
let patch_info = PatchInfo {
|
||||||
|
- uuid: Uuid::new_v4().to_string(),
|
||||||
|
+ uuid: Uuid::new_v4(),
|
||||||
|
name: kbuild_params.patch_name.to_owned(),
|
||||||
|
kind: kbuild_params.patch_type,
|
||||||
|
version: kbuild_params.patch_version.to_owned(),
|
||||||
|
diff --git a/syscare-build/src/patch/metadata.rs b/syscare-build/src/patch/metadata.rs
|
||||||
|
index 284c096..918b487 100644
|
||||||
|
--- a/syscare-build/src/patch/metadata.rs
|
||||||
|
+++ b/syscare-build/src/patch/metadata.rs
|
||||||
|
@@ -16,6 +16,8 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
+use uuid::Uuid;
|
||||||
|
+
|
||||||
|
use syscare_abi::{PatchInfo, PATCH_INFO_MAGIC};
|
||||||
|
use syscare_common::{fs, util::serde};
|
||||||
|
|
||||||
|
@@ -61,7 +63,7 @@ impl PatchMetadata {
|
||||||
|
}
|
||||||
|
|
||||||
|
let patch_info = PatchInfo {
|
||||||
|
- uuid: String::default(),
|
||||||
|
+ uuid: Uuid::default(),
|
||||||
|
name: build_params.patch_name.to_owned(),
|
||||||
|
version: build_params.patch_version.to_owned(),
|
||||||
|
release: build_params.patch_release.to_owned(),
|
||||||
|
diff --git a/syscare-build/src/patch/user_patch/upatch_builder.rs b/syscare-build/src/patch/user_patch/upatch_builder.rs
|
||||||
|
index ad8710b..1e0e6b6 100644
|
||||||
|
--- a/syscare-build/src/patch/user_patch/upatch_builder.rs
|
||||||
|
+++ b/syscare-build/src/patch/user_patch/upatch_builder.rs
|
||||||
|
@@ -259,7 +259,7 @@ impl UserPatchBuilder {
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(patch_file) = patch_entity_map.get(&elf_name) {
|
||||||
|
- let entity_uuid = Uuid::new_v4().to_string();
|
||||||
|
+ let entity_uuid = Uuid::new_v4();
|
||||||
|
let entity_name = fs::file_name(patch_file);
|
||||||
|
let entity_target = elf_file.to_owned();
|
||||||
|
let entity_checksum = digest::file(patch_file).with_context(|| {
|
||||||
|
@@ -277,7 +277,7 @@ impl UserPatchBuilder {
|
||||||
|
}
|
||||||
|
|
||||||
|
let patch_info = PatchInfo {
|
||||||
|
- uuid: Uuid::new_v4().to_string(),
|
||||||
|
+ uuid: Uuid::new_v4(),
|
||||||
|
name: ubuild_params.patch_name.to_owned(),
|
||||||
|
kind: ubuild_params.patch_type,
|
||||||
|
version: ubuild_params.patch_version.to_owned(),
|
||||||
|
diff --git a/syscared/src/patch/resolver/kpatch.rs b/syscared/src/patch/resolver/kpatch.rs
|
||||||
|
index 7de81b3..50711eb 100644
|
||||||
|
--- a/syscared/src/patch/resolver/kpatch.rs
|
||||||
|
+++ b/syscared/src/patch/resolver/kpatch.rs
|
||||||
|
@@ -16,13 +16,11 @@ use std::{
|
||||||
|
ffi::OsString,
|
||||||
|
os::unix::ffi::OsStringExt,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
- str::FromStr,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Context, Result};
|
||||||
|
use object::{NativeFile, Object, ObjectSection};
|
||||||
|
-use uuid::Uuid;
|
||||||
|
|
||||||
|
use syscare_abi::{PatchEntity, PatchInfo, PatchType};
|
||||||
|
use syscare_common::{concat_os, ffi::OsStrExt, fs};
|
||||||
|
@@ -194,7 +192,7 @@ impl PatchResolverImpl for KpatchResolverImpl {
|
||||||
|
.join(KPATCH_SYS_FILE_NAME);
|
||||||
|
|
||||||
|
let mut patch = KernelPatch {
|
||||||
|
- uuid: Uuid::from_str(&patch_entity.uuid).context("Invalid patch uuid")?,
|
||||||
|
+ uuid: patch_entity.uuid,
|
||||||
|
name: concat_os!(
|
||||||
|
patch_info.target.short_name(),
|
||||||
|
"/",
|
||||||
|
diff --git a/syscared/src/patch/resolver/upatch.rs b/syscared/src/patch/resolver/upatch.rs
|
||||||
|
index 507bf8e..15c7363 100644
|
||||||
|
--- a/syscared/src/patch/resolver/upatch.rs
|
||||||
|
+++ b/syscared/src/patch/resolver/upatch.rs
|
||||||
|
@@ -12,11 +12,10 @@
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::Path, str::FromStr, sync::Arc};
|
||||||
|
+use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::Path, sync::Arc};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Context, Result};
|
||||||
|
use object::{NativeFile, Object, ObjectSection};
|
||||||
|
-use uuid::Uuid;
|
||||||
|
|
||||||
|
use syscare_abi::{PatchEntity, PatchInfo, PatchType};
|
||||||
|
use syscare_common::{concat_os, fs};
|
||||||
|
@@ -152,7 +151,7 @@ impl PatchResolverImpl for UpatchResolverImpl {
|
||||||
|
patch_entity: &PatchEntity,
|
||||||
|
) -> Result<Patch> {
|
||||||
|
let mut patch = UserPatch {
|
||||||
|
- uuid: Uuid::from_str(&patch_entity.uuid).context("Invalid patch uuid")?,
|
||||||
|
+ uuid: patch_entity.uuid,
|
||||||
|
name: concat_os!(
|
||||||
|
patch_info.target.short_name(),
|
||||||
|
"/",
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
103
0006-syscared-optimize-patch-error-logic.patch
Normal file
103
0006-syscared-optimize-patch-error-logic.patch
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
From 1fbb81935c66c47a68716580878f2b983272a2bc Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Fri, 12 Apr 2024 11:35:57 +0800
|
||||||
|
Subject: [PATCH 06/10] syscared: optimize patch error logic
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
syscared/src/patch/driver/upatch/mod.rs | 21 +++++++++++----------
|
||||||
|
syscared/src/patch/driver/upatch/sys.rs | 4 ++--
|
||||||
|
2 files changed, 13 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
index a7fa154..0b82db9 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/mod.rs
|
||||||
|
@@ -56,8 +56,7 @@ pub struct UserPatchDriver {
|
||||||
|
impl UserPatchDriver {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let elf_patch_map = Arc::new(Mutex::new(IndexMap::new()));
|
||||||
|
- let patch_monitor =
|
||||||
|
- UserPatchMonitor::new(elf_patch_map.clone(), Self::patch_new_process)?;
|
||||||
|
+ let patch_monitor = UserPatchMonitor::new(elf_patch_map.clone(), Self::patch_new_process)?;
|
||||||
|
|
||||||
|
let instance = Self {
|
||||||
|
patch_target_map: IndexMap::new(),
|
||||||
|
@@ -196,8 +195,10 @@ impl UserPatchDriver {
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for pid in &need_active {
|
||||||
|
- if let Err(e) = sys::active_patch(uuid, *pid, target_elf, patch_file) {
|
||||||
|
- error!("{:?}", e);
|
||||||
|
+ if let Err(e) = sys::active_patch(uuid, *pid, target_elf, patch_file)
|
||||||
|
+ .with_context(|| format!("Failed to patch process, pid={}", pid))
|
||||||
|
+ {
|
||||||
|
+ error!("{}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
patch_record.processes.insert(*pid);
|
||||||
|
@@ -262,7 +263,7 @@ impl UserPatchDriver {
|
||||||
|
);
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
- "Upatch: Applying patch '{}', patch_file: {}",
|
||||||
|
+ "Upatch: Applying patch '{}' ({})",
|
||||||
|
patch_uuid,
|
||||||
|
patch.patch_file.display()
|
||||||
|
);
|
||||||
|
@@ -281,7 +282,7 @@ impl UserPatchDriver {
|
||||||
|
);
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
- "Upatch: Removing patch '{}', patch_file: {}",
|
||||||
|
+ "Upatch: Removing patch '{}' ({})",
|
||||||
|
patch_uuid,
|
||||||
|
patch.patch_file.display()
|
||||||
|
);
|
||||||
|
@@ -326,9 +327,8 @@ impl UserPatchDriver {
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for pid in need_active {
|
||||||
|
- if let Err(e) = sys::active_patch(&uuid, pid, target_elf, patch_file) {
|
||||||
|
- error!("{:?}", e);
|
||||||
|
- }
|
||||||
|
+ sys::active_patch(&uuid, pid, target_elf, patch_file)
|
||||||
|
+ .with_context(|| format!("Failed to patch process, pid={}", pid))?;
|
||||||
|
patch_record.processes.insert(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -394,7 +394,8 @@ impl UserPatchDriver {
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for pid in need_deactive {
|
||||||
|
- sys::deactive_patch(&uuid, pid, target_elf, patch_file)?;
|
||||||
|
+ sys::deactive_patch(&uuid, pid, target_elf, patch_file)
|
||||||
|
+ .with_context(|| format!("Failed to unpatch process, pid={}", pid))?;
|
||||||
|
patch_record.processes.remove(&pid); // remove process from record
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
index f0745f0..1908520 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
@@ -20,7 +20,7 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Debug)
|
||||||
|
+ .stdout(Level::Info)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Pat
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Debug)
|
||||||
|
+ .stdout(Level::Info)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
112
0007-syscared-optimize-transaction-creation-logic.patch
Normal file
112
0007-syscared-optimize-transaction-creation-logic.patch
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
From bbf3396adbbd53709ab5a78c1035e6b9b010d549 Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Fri, 12 Apr 2024 11:40:25 +0800
|
||||||
|
Subject: [PATCH 07/10] syscared: optimize transaction creation logic
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
syscared/src/patch/driver/upatch/sys.rs | 4 ++--
|
||||||
|
syscared/src/patch/transaction.rs | 9 +++------
|
||||||
|
syscared/src/rpc/skeleton_impl/patch.rs | 10 +++++-----
|
||||||
|
3 files changed, 10 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
index 1908520..f0745f0 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
@@ -20,7 +20,7 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Info)
|
||||||
|
+ .stdout(Level::Debug)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Pat
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Info)
|
||||||
|
+ .stdout(Level::Debug)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/transaction.rs b/syscared/src/patch/transaction.rs
|
||||||
|
index a3c5dda..695532c 100644
|
||||||
|
--- a/syscared/src/patch/transaction.rs
|
||||||
|
+++ b/syscared/src/patch/transaction.rs
|
||||||
|
@@ -43,18 +43,15 @@ where
|
||||||
|
action: F,
|
||||||
|
flag: PatchOpFlag,
|
||||||
|
identifier: String,
|
||||||
|
- ) -> Result<Self> {
|
||||||
|
- let instance = Self {
|
||||||
|
+ ) -> Self {
|
||||||
|
+ Self {
|
||||||
|
name,
|
||||||
|
patch_manager,
|
||||||
|
action,
|
||||||
|
identifier,
|
||||||
|
flag,
|
||||||
|
finish_list: Vec::new(),
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- debug!("{} is created", instance);
|
||||||
|
- Ok(instance)
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/syscared/src/rpc/skeleton_impl/patch.rs b/syscared/src/rpc/skeleton_impl/patch.rs
|
||||||
|
index 98494b1..b009d46 100644
|
||||||
|
--- a/syscared/src/rpc/skeleton_impl/patch.rs
|
||||||
|
+++ b/syscared/src/rpc/skeleton_impl/patch.rs
|
||||||
|
@@ -101,7 +101,7 @@ impl PatchSkeleton for PatchSkeletonImpl {
|
||||||
|
true => PatchOpFlag::Force,
|
||||||
|
},
|
||||||
|
identifier,
|
||||||
|
- )?
|
||||||
|
+ )
|
||||||
|
.invoke()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -115,7 +115,7 @@ impl PatchSkeleton for PatchSkeletonImpl {
|
||||||
|
PatchManager::remove_patch,
|
||||||
|
PatchOpFlag::Normal,
|
||||||
|
identifier,
|
||||||
|
- )?
|
||||||
|
+ )
|
||||||
|
.invoke()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -136,7 +136,7 @@ impl PatchSkeleton for PatchSkeletonImpl {
|
||||||
|
true => PatchOpFlag::Force,
|
||||||
|
},
|
||||||
|
identifier,
|
||||||
|
- )?
|
||||||
|
+ )
|
||||||
|
.invoke()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -150,7 +150,7 @@ impl PatchSkeleton for PatchSkeletonImpl {
|
||||||
|
PatchManager::deactive_patch,
|
||||||
|
PatchOpFlag::Normal,
|
||||||
|
identifier,
|
||||||
|
- )?
|
||||||
|
+ )
|
||||||
|
.invoke()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -164,7 +164,7 @@ impl PatchSkeleton for PatchSkeletonImpl {
|
||||||
|
PatchManager::accept_patch,
|
||||||
|
PatchOpFlag::Normal,
|
||||||
|
identifier,
|
||||||
|
- )?
|
||||||
|
+ )
|
||||||
|
.invoke()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
136
0008-upatch-manage-optimize-output.patch
Normal file
136
0008-upatch-manage-optimize-output.patch
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
From 7c976ffc72330c85bc815bc1983dd7096778bf1b Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Fri, 12 Apr 2024 11:50:59 +0800
|
||||||
|
Subject: [PATCH 08/10] upatch-manage: optimize output
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
upatch-manage/upatch-manage.c | 2 +-
|
||||||
|
upatch-manage/upatch-patch.c | 10 +++++-----
|
||||||
|
upatch-manage/upatch-process.c | 23 ++++++++++++-----------
|
||||||
|
3 files changed, 18 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/upatch-manage/upatch-manage.c b/upatch-manage/upatch-manage.c
|
||||||
|
index a5973e4..e33eeb3 100644
|
||||||
|
--- a/upatch-manage/upatch-manage.c
|
||||||
|
+++ b/upatch-manage/upatch-manage.c
|
||||||
|
@@ -152,7 +152,7 @@ int patch_upatch(const char *uuid, const char *binary_path, const char *upatch_p
|
||||||
|
|
||||||
|
ret = process_patch(pid, &uelf, &relf, uuid, binary_path);
|
||||||
|
if (ret) {
|
||||||
|
- log_error("Failed to patch process, pid=%d ret=%d\n", pid, ret);
|
||||||
|
+ log_error("Failed to patch process, pid=%d, ret=%d\n", pid, ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
log_normal("SUCCESS\n");
|
||||||
|
diff --git a/upatch-manage/upatch-patch.c b/upatch-manage/upatch-patch.c
|
||||||
|
index bda4e10..5e16002 100644
|
||||||
|
--- a/upatch-manage/upatch-patch.c
|
||||||
|
+++ b/upatch-manage/upatch-patch.c
|
||||||
|
@@ -712,6 +712,7 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ printf("Patch ");
|
||||||
|
upatch_process_print_short(&proc);
|
||||||
|
|
||||||
|
ret = upatch_process_mem_open(&proc, MEM_READ);
|
||||||
|
@@ -768,8 +769,7 @@ out:
|
||||||
|
if (is_calc_time) {
|
||||||
|
gettimeofday(&end_tv, NULL);
|
||||||
|
frozen_time = GET_MICROSECONDS(end_tv, start_tv);
|
||||||
|
- log_normal(
|
||||||
|
- "PID '%d' process patch frozen_time is %ld microsecond\n",
|
||||||
|
+ log_normal("Process %d frozen time is %ld microsecond(s)\n",
|
||||||
|
pid, frozen_time);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
@@ -831,10 +831,11 @@ int process_unpatch(int pid, const char *uuid)
|
||||||
|
// 查看process的信息,pid: maps, mem, cmdline, exe
|
||||||
|
ret = upatch_process_init(&proc, pid);
|
||||||
|
if (ret < 0) {
|
||||||
|
- log_error("cannot init process %d\n", pid);
|
||||||
|
+ log_error("Failed to init process %d, ret=%d\n", pid, ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ printf("Unpatch ");
|
||||||
|
upatch_process_print_short(&proc);
|
||||||
|
|
||||||
|
ret = upatch_process_mem_open(&proc, MEM_READ);
|
||||||
|
@@ -880,8 +881,7 @@ out:
|
||||||
|
if (is_calc_time) {
|
||||||
|
gettimeofday(&end_tv, NULL);
|
||||||
|
frozen_time = GET_MICROSECONDS(end_tv, start_tv);
|
||||||
|
- log_normal(
|
||||||
|
- "PID '%d' process patch frozen_time is %ld microsecond\n",
|
||||||
|
+ log_normal("Process %d frozen time is %ld microsecond(s)\n",
|
||||||
|
pid, frozen_time);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
diff --git a/upatch-manage/upatch-process.c b/upatch-manage/upatch-process.c
|
||||||
|
index 0d57238..cd3f7e0 100644
|
||||||
|
--- a/upatch-manage/upatch-process.c
|
||||||
|
+++ b/upatch-manage/upatch-process.c
|
||||||
|
@@ -204,30 +204,31 @@ static void process_print_cmdline(struct upatch_process *proc)
|
||||||
|
snprintf(buf, PATH_MAX, "/proc/%d/cmdline", proc->pid);
|
||||||
|
int fd = open(buf, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
- log_error("open\n");
|
||||||
|
+ log_error("Failed to open %s", buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
rv = read(fd, buf, sizeof(buf));
|
||||||
|
|
||||||
|
- if (rv == -1 && errno == EINTR)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
if (rv == -1) {
|
||||||
|
- log_error("read\n");
|
||||||
|
+ if (errno == EINTR) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ log_error("Failed to read cmdline\n");
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (rv == 0)
|
||||||
|
+ if (rv == 0) {
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
for (i = 0; i < rv; i++) {
|
||||||
|
- if (buf[i] != '\n' && isprint(buf[i])) {
|
||||||
|
- putchar(buf[i]);
|
||||||
|
+ if (isprint(buf[i])) {
|
||||||
|
+ printf("%c", buf[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- printf("\\x%02x", (unsigned char)buf[i]);
|
||||||
|
+ printf(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -238,7 +239,7 @@ err_close:
|
||||||
|
|
||||||
|
void upatch_process_print_short(struct upatch_process *proc)
|
||||||
|
{
|
||||||
|
- printf("upatch target pid %d, cmdline:", proc->pid);
|
||||||
|
+ printf("process %d, cmdline: ", proc->pid);
|
||||||
|
process_print_cmdline(proc);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
@@ -254,7 +255,7 @@ int upatch_process_mem_open(struct upatch_process *proc, int mode)
|
||||||
|
snprintf(path, sizeof(path), "/proc/%d/mem", proc->pid);
|
||||||
|
proc->memfd = open(path, mode == MEM_WRITE ? O_RDWR : O_RDONLY);
|
||||||
|
if (proc->memfd < 0) {
|
||||||
|
- log_error("can't open /proc/%d/mem", proc->pid);
|
||||||
|
+ log_error("Failed to open %s", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
35
0009-syscared-optimize-patch-error-logic.patch
Normal file
35
0009-syscared-optimize-patch-error-logic.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 1a419fd88160f45a8fdabd8e6427811804735af1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Fri, 12 Apr 2024 11:35:57 +0800
|
||||||
|
Subject: [PATCH 09/10] syscared: optimize patch error logic
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
syscared/src/patch/driver/upatch/sys.rs | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
index f0745f0..1908520 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
@@ -20,7 +20,7 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Debug)
|
||||||
|
+ .stdout(Level::Info)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Pat
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Debug)
|
||||||
|
+ .stdout(Level::Info)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
35
0010-syscared-optimize-transaction-creation-logic.patch
Normal file
35
0010-syscared-optimize-transaction-creation-logic.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 91b63792ed2b13ce8fc706df1ffa7d9fdadc31c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: renoseven <dev@renoseven.net>
|
||||||
|
Date: Fri, 12 Apr 2024 11:40:25 +0800
|
||||||
|
Subject: [PATCH 10/10] syscared: optimize transaction creation logic
|
||||||
|
|
||||||
|
Signed-off-by: renoseven <dev@renoseven.net>
|
||||||
|
---
|
||||||
|
syscared/src/patch/driver/upatch/sys.rs | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
index 1908520..f0745f0 100644
|
||||||
|
--- a/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
+++ b/syscared/src/patch/driver/upatch/sys.rs
|
||||||
|
@@ -20,7 +20,7 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Info)
|
||||||
|
+ .stdout(Level::Debug)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Pat
|
||||||
|
.arg(target_elf)
|
||||||
|
.arg("--upatch")
|
||||||
|
.arg(patch_file)
|
||||||
|
- .stdout(Level::Info)
|
||||||
|
+ .stdout(Level::Debug)
|
||||||
|
.run_with_output()?
|
||||||
|
.exit_code();
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
||||||
Binary file not shown.
33
syscare.spec
33
syscare.spec
@ -11,12 +11,23 @@
|
|||||||
############################################
|
############################################
|
||||||
Name: syscare
|
Name: syscare
|
||||||
Version: 1.2.1
|
Version: 1.2.1
|
||||||
Release: 2
|
Release: 3
|
||||||
Summary: System hot-fix service
|
Summary: System hot-fix service
|
||||||
License: MulanPSL-2.0 and GPL-2.0-only
|
License: MulanPSL-2.0 and GPL-2.0-only
|
||||||
URL: https://gitee.com/openeuler/syscare
|
URL: https://gitee.com/openeuler/syscare
|
||||||
Source0: %{name}-%{version}.tar.gz
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
|
||||||
|
Patch0001: 0001-upatch-hijacker-fix-compile-bug.patch
|
||||||
|
Patch0002: 0002-daemon-fix-cannot-get-file-selinux-xattr-when-selinu.patch
|
||||||
|
Patch0003: 0003-syscared-fix-syscare-check-command-does-not-check-sy.patch
|
||||||
|
Patch0004: 0004-syscared-fix-cannot-find-process-of-dynlib-patch-iss.patch
|
||||||
|
Patch0005: 0005-abi-change-uuid-type-from-string-to-uuid-bytes.patch
|
||||||
|
Patch0006: 0006-syscared-optimize-patch-error-logic.patch
|
||||||
|
Patch0007: 0007-syscared-optimize-transaction-creation-logic.patch
|
||||||
|
Patch0008: 0008-upatch-manage-optimize-output.patch
|
||||||
|
Patch0009: 0009-syscared-optimize-patch-error-logic.patch
|
||||||
|
Patch0010: 0010-syscared-optimize-transaction-creation-logic.patch
|
||||||
|
|
||||||
BuildRequires: cmake >= 3.14 make
|
BuildRequires: cmake >= 3.14 make
|
||||||
BuildRequires: rust >= 1.51 cargo >= 1.51
|
BuildRequires: rust >= 1.51 cargo >= 1.51
|
||||||
BuildRequires: gcc gcc-c++
|
BuildRequires: gcc gcc-c++
|
||||||
@ -60,9 +71,11 @@ systemctl start syscare
|
|||||||
|
|
||||||
############### PreUninstall ###############
|
############### PreUninstall ###############
|
||||||
%preun
|
%preun
|
||||||
systemctl daemon-reload
|
if [ "$1" -eq 0 ]; then
|
||||||
systemctl stop syscare
|
systemctl daemon-reload
|
||||||
systemctl disable syscare
|
systemctl stop syscare
|
||||||
|
systemctl disable syscare
|
||||||
|
fi
|
||||||
|
|
||||||
############## PostUninstall ###############
|
############## PostUninstall ###############
|
||||||
%postun
|
%postun
|
||||||
@ -164,6 +177,18 @@ fi
|
|||||||
################ Change log ################
|
################ Change log ################
|
||||||
############################################
|
############################################
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Apr 12 2024 ningyu<ningyu9@huawei.com> - 1.2.1-3
|
||||||
|
- upatch-hijacker: fix compile bug
|
||||||
|
- daemon: fix 'cannot get file selinux xattr when selinux is not enforcing' issue
|
||||||
|
- syscared: fix 'syscare check command does not check symbol confiliction' issue
|
||||||
|
- syscared: fix 'cannot find process of dynlib patch' issue
|
||||||
|
- Change uuid type from string to uuid bytes
|
||||||
|
- syscared: optimize patch error logic
|
||||||
|
- syscared: optimize transaction creation logic
|
||||||
|
- upatch-manage: optimize output
|
||||||
|
- syscared: optimize patch error logic
|
||||||
|
- syscared: optimize transaction creation logic
|
||||||
|
- spec: fix "cannot find syscare service after upgrade" bug
|
||||||
* Sun Apr 7 2024 ningyu<ningyu9@huawei.com> - 1.2.1-2
|
* Sun Apr 7 2024 ningyu<ningyu9@huawei.com> - 1.2.1-2
|
||||||
- update to syscare.1.2.1-2
|
- update to syscare.1.2.1-2
|
||||||
* Thu Mar 28 2024 ningyu<ningyu9@huawei.com> - 1.2.1-1
|
* Thu Mar 28 2024 ningyu<ningyu9@huawei.com> - 1.2.1-1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user