Compare commits

...

11 Commits

Author SHA1 Message Date
renoseven
c1f9f18710 update to 1.2.2-3
Signed-off-by: renoseven <dev@renoseven.net>
2024-11-11 11:49:46 +08:00
openeuler-ci-bot
d3eeebde8d
!215 [sync] PR-214: update openEuler-24.03-LTS to 1.2.1-10
From: @openeuler-sync-bot 
Reviewed-by: @snoweay 
Signed-off-by: @snoweay
2024-08-16 09:50:48 +00:00
renoseven
f67452bd87 update to 1.2.1-10
Signed-off-by: renoseven <dev@renoseven.net>
(cherry picked from commit aaca4c9c5f8db3a4546717038fc2416ba0547eb9)
2024-08-16 17:17:35 +08:00
renoseven
b979222579 update scripts
Signed-off-by: renoseven <dev@renoseven.net>
(cherry picked from commit 27bb77c6994f901ec8a54ab54b9d143f54905617)
2024-08-16 17:17:35 +08:00
renoseven
2d6e0a7e12 add generate patch script
Signed-off-by: renoseven <dev@renoseven.net>
(cherry picked from commit 2901ec3d3ce68ece2d1c9a2f4cbba9ae457fc0fa)
2024-08-16 17:17:35 +08:00
yueyuankun
58861bbf9b add excludearch loongarch64
(cherry picked from commit 37c1009563141ba5ea16453ed4e7651d28275388)
2024-08-15 09:50:50 +08:00
ningyu
70a0c674b8 update to 1.2.1-8
syscared: fix apply kernel module patch failure issue
syscare-build: fix build oot module failure issue

Signed-off-by: ningyu <405888464@qq.com>
(cherry picked from commit 9dd2411f7200156f930b61f1650a5d31659f3a9a)
2024-05-23 15:09:53 +08:00
openeuler-ci-bot
da4216e70e
!192 [sync] PR-188: update to 1.2.1-7
From: @openeuler-sync-bot 
Reviewed-by: @solarhu 
Signed-off-by: @solarhu
2024-05-14 10:38:20 +00:00
ningyu
87cdeb62d3 update to 1.2.1-7
Signed-off-by: ningyu <405888464@qq.com>
(cherry picked from commit 4ee0e0f02e7c125d9ecd8114481e9867b6153e79)
2024-05-14 18:30:39 +08:00
openeuler-ci-bot
c94a743994
!186 [sync] PR-185: update syscare to 1.2.1-6
From: @openeuler-sync-bot 
Reviewed-by: @snoweay 
Signed-off-by: @snoweay
2024-05-13 02:48:26 +00:00
renoseven
28fec1a652 update to 1.2.1-6
Signed-off-by: renoseven <dev@renoseven.net>
(cherry picked from commit 6f0c82e94705c107961b29f439493987d3ba15d9)
2024-05-11 21:20:20 +08:00
21 changed files with 102 additions and 5457 deletions

View File

@ -1,33 +0,0 @@
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/17] 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

View File

@ -1,219 +0,0 @@
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/17] 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

View File

@ -1,385 +0,0 @@
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/17] 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

View File

@ -1,222 +0,0 @@
From b53cb3d2903ea8ee3667f892b813648da7bc59a7 Mon Sep 17 00:00:00 2001
From: ningyu <ningyu9@huawei.com>
Date: Tue, 9 Apr 2024 09:21:35 +0000
Subject: [PATCH 04/17] Change uuid type to Uuid
---
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..5570c34 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

View File

@ -1,39 +0,0 @@
From 41e5b9125fab50d4b3a137c5397443319e2365ec Mon Sep 17 00:00:00 2001
From: ningyu <405888464@qq.com>
Date: Wed, 10 Apr 2024 17:19:35 +0800
Subject: [PATCH 05/17] fix clippy warning
---
syscare-build/src/package/rpm/spec_builder.rs | 2 +-
syscared/src/patch/driver/upatch/mod.rs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/syscare-build/src/package/rpm/spec_builder.rs b/syscare-build/src/package/rpm/spec_builder.rs
index 5570c34..a24954f 100644
--- a/syscare-build/src/package/rpm/spec_builder.rs
+++ b/syscare-build/src/package/rpm/spec_builder.rs
@@ -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.to_string());
+ let pkg_root = Path::new(PKG_INSTALL_DIR).join(patch_info.uuid.to_string());
let mut spec = RpmSpecFile::new(
pkg_name,
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
index 98fc54c..98b1e34 100644
--- a/syscared/src/patch/driver/upatch/mod.rs
+++ b/syscared/src/patch/driver/upatch/mod.rs
@@ -38,7 +38,7 @@ mod target;
use monitor::UserPatchMonitor;
use target::PatchTarget;
-pub(self) type ActivePatchMap = Arc<Mutex<IndexMap<PathBuf, ActivePatch>>>;
+type ActivePatchMap = Arc<Mutex<IndexMap<PathBuf, ActivePatch>>>;
#[derive(Default)]
struct ActivePatch {
--
2.41.0

View File

@ -1,687 +0,0 @@
From 729f32db079e2aace7cf355d480627b0bbf37e8c Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 10 Apr 2024 19:30:56 +0800
Subject: [PATCH 06/17] 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 98b1e34..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;
-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

View File

@ -1,103 +0,0 @@
From 520e46ddd8f393125509a436134255765c5960cc Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:35:57 +0800
Subject: [PATCH 07/17] 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

View File

@ -1,112 +0,0 @@
From 4ceb42b4a81cfb573aad4b4542f143be4c0ae90c Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:40:25 +0800
Subject: [PATCH 08/17] 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

View File

@ -1,136 +0,0 @@
From 399de1f2021ae91ee6fc1271b1ee4f2f5933eaf1 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:50:59 +0800
Subject: [PATCH 09/17] 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

View File

@ -1,35 +0,0 @@
From 51aa26c1eeb7514bceb0194b601de560c6b9d74a Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:35:57 +0800
Subject: [PATCH 10/17] 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

View File

@ -1,35 +0,0 @@
From 1d67bb57973cc0bc4b227c4359c15c4f31a1c82c Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:40:25 +0800
Subject: [PATCH 11/17] 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

View File

@ -1,47 +0,0 @@
From b64fa8df5ef916510e345cdd0382c32364d0c255 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 16 Apr 2024 12:44:11 +0800
Subject: [PATCH 12/17] common: impl CStr::from_bytes_with_next_nul()
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-common/src/ffi/c_str.rs | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/syscare-common/src/ffi/c_str.rs b/syscare-common/src/ffi/c_str.rs
index 060149a..4f3f26d 100644
--- a/syscare-common/src/ffi/c_str.rs
+++ b/syscare-common/src/ffi/c_str.rs
@@ -13,7 +13,7 @@
*/
use std::{
- ffi::{CStr, OsStr, OsString},
+ ffi::{CStr, CString, FromBytesWithNulError, OsStr, OsString},
os::unix::{ffi::OsStringExt, prelude::OsStrExt},
path::{Path, PathBuf},
};
@@ -34,9 +34,19 @@ pub trait CStrExt: AsRef<CStr> {
fn to_path_buf(&self) -> PathBuf {
PathBuf::from(self.to_os_string())
}
+
+ fn from_bytes_with_next_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> {
+ let nul_pos = bytes.iter().position(|b| b == &b'\0').unwrap_or(0);
+ let cstr_bytes = &bytes[..=nul_pos];
+
+ CStr::from_bytes_with_nul(cstr_bytes)
+ }
}
-impl<T: AsRef<CStr>> CStrExt for T {}
+impl CStrExt for CStr {}
+impl CStrExt for &CStr {}
+impl CStrExt for CString {}
+impl CStrExt for &CString {}
#[test]
fn test_cstr() {
--
2.41.0

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +0,0 @@
From 3ee829f2156651f2284e072ba63abd196ee43294 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 17 Apr 2024 19:14:19 +0800
Subject: [PATCH 14/17] syscared: stop activating ignored process on new
process start
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/patch/driver/kpatch/mod.rs | 8 +-
syscared/src/patch/driver/upatch/mod.rs | 109 ++++++++++++------------
2 files changed, 58 insertions(+), 59 deletions(-)
diff --git a/syscared/src/patch/driver/kpatch/mod.rs b/syscared/src/patch/driver/kpatch/mod.rs
index 45dc719..307efb5 100644
--- a/syscared/src/patch/driver/kpatch/mod.rs
+++ b/syscared/src/patch/driver/kpatch/mod.rs
@@ -239,7 +239,7 @@ impl KernelPatchDriver {
pub fn apply(&mut self, patch: &KernelPatch) -> Result<()> {
info!(
- "Kpatch: Applying patch '{}' ({})",
+ "Applying patch '{}' ({})",
patch.uuid,
patch.patch_file.display()
);
@@ -253,7 +253,7 @@ impl KernelPatchDriver {
pub fn remove(&mut self, patch: &KernelPatch) -> Result<()> {
info!(
- "Kpatch: Removing patch '{}' ({})",
+ "Removing patch '{}' ({})",
patch.uuid,
patch.patch_file.display()
);
@@ -265,7 +265,7 @@ impl KernelPatchDriver {
pub fn active(&mut self, patch: &KernelPatch) -> Result<()> {
info!(
- "Kpatch: Activating patch '{}' ({})",
+ "Activating patch '{}' ({})",
patch.uuid,
patch.patch_file.display()
);
@@ -277,7 +277,7 @@ impl KernelPatchDriver {
pub fn deactive(&mut self, patch: &KernelPatch) -> Result<()> {
info!(
- "Kpatch: Deactivating patch '{}' ({})",
+ "Deactivating patch '{}' ({})",
patch.uuid,
patch.patch_file.display()
);
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
index dd07e9b..66eecf5 100644
--- a/syscared/src/patch/driver/upatch/mod.rs
+++ b/syscared/src/patch/driver/upatch/mod.rs
@@ -237,21 +237,20 @@ impl UserPatchDriver {
patch_entity.clean_dead_process(&process_list);
// Active patch
- let need_actived = patch_entity.need_actived(&process_list);
+ let need_ignored = patch_entity.need_ignored(&process_list);
+
+ let mut need_actived = patch_entity.need_actived(&process_list);
+ need_actived.retain(|pid| !need_ignored.contains(pid));
if !need_actived.is_empty() {
debug!(
- "Upatch: Activating patch '{}' ({}) for process {:?}",
+ "Activating patch '{}' ({}) for process {:?}",
patch_uuid,
target_elf.display(),
need_actived,
);
}
- let ignore_list = patch_entity.need_ignored(&process_list);
for pid in need_actived {
- if ignore_list.contains(&pid) {
- continue;
- }
match sys::active_patch(patch_uuid, pid, target_elf, &patch_entity.patch_file) {
Ok(_) => patch_entity.add_process(pid),
Err(e) => {
@@ -283,7 +282,7 @@ impl UserPatchDriver {
pub fn apply(&mut self, patch: &UserPatch) -> Result<()> {
info!(
- "Upatch: Applying patch '{}' ({})",
+ "Applying patch '{}' ({})",
patch.uuid,
patch.patch_file.display()
);
@@ -296,7 +295,7 @@ impl UserPatchDriver {
pub fn remove(&mut self, patch: &UserPatch) -> Result<()> {
info!(
- "Upatch: Removing patch '{}' ({})",
+ "Removing patch '{}' ({})",
patch.uuid,
patch.patch_file.display()
);
@@ -326,7 +325,7 @@ impl UserPatchDriver {
// Active patch
info!(
- "Upatch: Activating patch '{}' ({}) for {}",
+ "Activating patch '{}' ({}) for {}",
patch_uuid,
patch_file.display(),
target_elf.display(),
@@ -342,29 +341,28 @@ impl UserPatchDriver {
}
// Check results, return error if all process fails
- match results.iter().any(|(_, result)| result.is_ok()) {
- true => {
- for (pid, result) in &results {
- if let Err(e) = result {
- warn!(
- "Upatch: Failed to active patch '{}' for process {}, {}",
- patch_uuid,
- pid,
- e.to_string().to_lowercase(),
- );
- }
+ if !results.is_empty() && results.iter().all(|(_, result)| result.is_err()) {
+ let mut err_msg = String::new();
+
+ writeln!(err_msg, "Upatch: Failed to active patch")?;
+ for (pid, result) in &results {
+ if let Err(e) = result {
+ writeln!(err_msg, "* Process {}: {}", pid, e)?;
}
}
- false => {
- let mut err_msg = String::new();
+ err_msg.pop();
+ bail!(err_msg);
+ }
- writeln!(err_msg, "Upatch: Failed to active patch")?;
- for (pid, result) in &results {
- if let Err(e) = result {
- writeln!(err_msg, "* Process {}: {}", pid, e)?;
- }
- }
- bail!(err_msg);
+ // Print failure results
+ for (pid, result) in &results {
+ if let Err(e) = result {
+ warn!(
+ "Upatch: Failed to active patch '{}' for process {}, {}",
+ patch_uuid,
+ pid,
+ e.to_string().to_lowercase(),
+ );
}
}
@@ -407,17 +405,19 @@ impl UserPatchDriver {
// Deactive patch
info!(
- "Upatch: Deactivating patch '{}' ({}) for {}",
+ "Deactivating patch '{}' ({}) for {}",
patch_uuid,
patch_file.display(),
target_elf.display(),
);
+
+ let need_ignored = patch_entity.need_ignored(&process_list);
+
+ let mut need_deactived = patch_entity.need_deactived(&process_list);
+ need_deactived.retain(|pid| need_ignored.contains(pid));
+
let mut results = Vec::new();
- let ignore_list = patch_entity.need_ignored(&process_list);
for pid in patch_entity.need_deactived(&process_list) {
- if ignore_list.contains(&pid) {
- continue;
- }
let result = sys::deactive_patch(patch_uuid, pid, target_elf, patch_file);
if result.is_ok() {
patch_entity.remove_process(pid)
@@ -426,29 +426,28 @@ impl UserPatchDriver {
}
// Check results, return error if any process failes
- match results.iter().any(|(_, result)| result.is_err()) {
- true => {
- let mut err_msg = String::new();
-
- writeln!(err_msg, "Upatch: Failed to deactive patch")?;
- for (pid, result) in &results {
- if let Err(e) = result {
- writeln!(err_msg, "* Process {}: {}", pid, e)?;
- }
+ if !results.is_empty() && results.iter().any(|(_, result)| result.is_err()) {
+ let mut err_msg = String::new();
+
+ writeln!(err_msg, "Upatch: Failed to deactive patch")?;
+ for (pid, result) in &results {
+ if let Err(e) = result {
+ writeln!(err_msg, "* Process {}: {}", pid, e)?;
}
- bail!(err_msg)
}
- false => {
- for (pid, result) in &results {
- if let Err(e) = result {
- warn!(
- "Upatch: Failed to deactive patch '{}' for process {}, {}",
- patch_uuid,
- pid,
- e.to_string().to_lowercase(),
- );
- }
- }
+ err_msg.pop();
+ bail!(err_msg);
+ }
+
+ // Print failure results
+ for (pid, result) in &results {
+ if let Err(e) = result {
+ warn!(
+ "Upatch: Failed to deactive patch '{}' for process {}, {}",
+ patch_uuid,
+ pid,
+ e.to_string().to_lowercase(),
+ );
}
}
--
2.41.0

View File

@ -1,35 +0,0 @@
From 96ccd901456d950761835befde8979519575778d Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 19 Apr 2024 12:02:23 +0800
Subject: [PATCH 15/17] syscared: adapt upatch-manage exit code change
1. upatch driver treats EEXIST as an error
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/patch/driver/upatch/sys.rs | 2 --
1 file changed, 2 deletions(-)
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
index bfeb1b8..a388bc6 100644
--- a/syscared/src/patch/driver/upatch/sys.rs
+++ b/syscared/src/patch/driver/upatch/sys.rs
@@ -2,7 +2,6 @@ use std::path::Path;
use anyhow::{bail, Result};
use log::Level;
-use nix::libc::EEXIST;
use uuid::Uuid;
use syscare_common::process::Command;
@@ -26,7 +25,6 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
match exit_code {
0 => Ok(()),
- EEXIST => Ok(()),
_ => bail!(std::io::Error::from_raw_os_error(exit_code)),
}
}
--
2.41.0

View File

@ -1,446 +0,0 @@
From 10dc2c5843156d032277cc0a3a85e2e8df3a5146 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 19 Apr 2024 12:01:38 +0800
Subject: [PATCH 16/17] upatch-manage: change exit code
1. return more specific exit code
2. change exit code from EEXIST to 0 when patching existing patch (uuid)
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-manage/log.h | 2 +-
upatch-manage/upatch-elf.c | 10 ++---
upatch-manage/upatch-manage.c | 7 ++--
upatch-manage/upatch-patch.c | 70 ++++++++++++++++++++--------------
upatch-manage/upatch-process.c | 15 ++------
upatch-manage/upatch-ptrace.c | 1 +
6 files changed, 56 insertions(+), 49 deletions(-)
diff --git a/upatch-manage/log.h b/upatch-manage/log.h
index a41bfc8..32e9c56 100644
--- a/upatch-manage/log.h
+++ b/upatch-manage/log.h
@@ -52,7 +52,7 @@ enum exit_status {
/* it is time cost */
#define log_debug(format, ...) log(DEBUG, format, ##__VA_ARGS__)
#define log_normal(format, ...) log(NORMAL, format, ##__VA_ARGS__)
-#define log_warn(format, ...) log(WARN, "%s: " format, logprefix, ##__VA_ARGS__)
+#define log_warn(format, ...) log(WARN, format, ##__VA_ARGS__)
#define log_error(format, ...) log(ERR, format, ##__VA_ARGS__)
#define log(level, format, ...) \
diff --git a/upatch-manage/upatch-elf.c b/upatch-manage/upatch-elf.c
index 165f0cf..02444eb 100644
--- a/upatch-manage/upatch-elf.c
+++ b/upatch-manage/upatch-elf.c
@@ -54,20 +54,20 @@ static int open_elf(struct elf_info *einfo, const char *name)
fd = open(name, O_RDONLY);
if (fd == -1) {
ret = -errno;
- log_error("Failed to open file '%s', ret=%d\n", name, ret);
+ log_error("Failed to open file '%s'\n", name);
goto out;
}
ret = stat(name, &st);
if (ret != 0) {
ret = -errno;
- log_error("Failed to stat file '%s', ret=%d\n", name, ret);
+ log_error("Failed to stat file '%s'\n", name);
goto out;
}
ret = read_from_offset(fd, (void **)&einfo->patch_buff, st.st_size, 0);
if (ret != 0) {
- log_error("Failed to read file '%s', ret=%d\n", name, ret);
+ log_error("Failed to read file '%s'\n", name);
goto out;
}
@@ -112,7 +112,7 @@ int upatch_init(struct upatch_elf *uelf, const char *name)
{
int ret = open_elf(&uelf->info, name);
if (ret) {
- log_error("Failed to open elf '%s', ret=%d\n", name, ret);
+ log_error("Failed to open file '%s'\n", name);
return ret;
}
@@ -136,7 +136,7 @@ int binary_init(struct running_elf *relf, const char *name)
{
int ret = open_elf(&relf->info, name);
if (ret) {
- log_error("Failed to open elf '%s', ret=%d\n", name, ret);
+ log_error("Failed to open file '%s'\n", name);
return ret;
}
diff --git a/upatch-manage/upatch-manage.c b/upatch-manage/upatch-manage.c
index e33eeb3..8a7ba60 100644
--- a/upatch-manage/upatch-manage.c
+++ b/upatch-manage/upatch-manage.c
@@ -146,7 +146,7 @@ int patch_upatch(const char *uuid, const char *binary_path, const char *upatch_p
int ret = upatch_init(&uelf, upatch_path);
if (ret) {
- log_error("Failed to initialize patch, ret=%d\n", ret);
+ log_error("Failed to initialize patch, pid=%d, ret=%d\n", pid, ret);
goto out;
}
@@ -155,7 +155,6 @@ int patch_upatch(const char *uuid, const char *binary_path, const char *upatch_p
log_error("Failed to patch process, pid=%d, ret=%d\n", pid, ret);
goto out;
}
- log_normal("SUCCESS\n");
out:
upatch_close(&uelf);
@@ -173,7 +172,6 @@ int unpatch_upatch(const char *uuid, const char *binary_path, const char *upatch
log_error("Failed to unpatch process, pid=%d, ret=%d\n", pid, ret);
return ret;
}
- log_normal("SUCCESS\n");
return 0;
}
@@ -185,7 +183,6 @@ int info_upatch(const char *binary_path, const char *upatch_path, int pid)
log_error("Failed to get patch info, pid=%d, ret=%d\n", pid, ret);
return ret;
}
- log_normal("SUCCESS\n");
return 0;
}
@@ -207,6 +204,7 @@ int main(int argc, char *argv[])
log_debug("Patch: %s\n", args.upatch);
log_debug("Binary: %s\n", args.binary);
+ args.pid = args.pid & INT32_MAX;
switch (args.cmd) {
case PATCH:
ret = patch_upatch(args.uuid, args.binary, args.upatch, args.pid);
@@ -223,5 +221,6 @@ int main(int argc, char *argv[])
break;
}
+ (ret == 0) ? log_normal("SUCCESS\n\n") : log_error("FAILED\n\n");
return abs(ret);
}
diff --git a/upatch-manage/upatch-patch.c b/upatch-manage/upatch-patch.c
index 5e16002..5a8f927 100644
--- a/upatch-manage/upatch-patch.c
+++ b/upatch-manage/upatch-patch.c
@@ -291,7 +291,6 @@ static void *upatch_alloc(struct object_file *obj, size_t sz)
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1,
0);
if (addr == 0) {
- log_error("Failed to alloc remote patch memory\n");
return NULL;
}
@@ -308,7 +307,7 @@ static void *upatch_alloc(struct object_file *obj, size_t sz)
return (void *)addr;
}
-static void __upatch_memfree(struct object_file *obj, void *base,
+static void upatch_free(struct object_file *obj, void *base,
unsigned int size)
{
log_debug("Free patch memory %p\n", base);
@@ -323,14 +322,13 @@ static int __alloc_memory(struct object_file *obj_file,
/* Do the allocs. */
layout->base = upatch_alloc(obj_file, layout->size);
if (!layout->base) {
- log_error("Failed to alloc patch core layout %p\n", layout->base);
- return -ENOMEM;
+ return -errno;
}
layout->kbase = malloc(layout->size);
if (!layout->kbase) {
- __upatch_memfree(obj_file, layout->base, layout->size);
- return -ENOMEM;
+ upatch_free(obj_file, layout->base, layout->size);
+ return -errno;
}
memset(layout->kbase, 0, layout->size);
@@ -345,7 +343,6 @@ static int alloc_memory(struct upatch_elf *uelf, struct object_file *obj)
/* Do the allocs. */
ret = __alloc_memory(obj, &uelf->core_layout);
if (ret) {
- log_error("Failed to alloc patch memory, ret=%d\n", ret);
return ret;
}
@@ -634,11 +631,13 @@ static int upatch_apply_patches(struct upatch_process *proc,
*/
ret = alloc_memory(uelf, obj);
if (ret) {
+ log_error("Failed to alloc patch memory\n");
goto free;
}
ret = upatch_mprotect(uelf, obj);
if (ret) {
+ log_error("Failed to set patch memory permission\n");
goto free;
}
@@ -675,7 +674,7 @@ static int upatch_apply_patches(struct upatch_process *proc,
// TODO: clear
free:
- __upatch_memfree(obj, uelf->core_layout.base, uelf->core_layout.size);
+ upatch_free(obj, uelf->core_layout.base, uelf->core_layout.size);
out:
return ret;
}
@@ -708,15 +707,16 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
// 查看process的信息pid: maps, mem, cmdline, exe
ret = upatch_process_init(&proc, pid);
if (ret < 0) {
- log_error("Failed to init process %d, ret=%d\n", pid, ret);
+ log_error("Failed to init process\n");
goto out;
}
- printf("Patch ");
+ printf("Patch '%s' to ", uuid);
upatch_process_print_short(&proc);
ret = upatch_process_mem_open(&proc, MEM_READ);
if (ret < 0) {
+ log_error("Failed to open process memory\n");
goto out_free;
}
@@ -731,15 +731,19 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
*/
// 解析process的mem-maps获得各个块的内存映射以及phdr
ret = upatch_process_map_object_files(&proc, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ log_error("Failed to read process memory mapping\n");
goto out_free;
+ }
ret = upatch_process_uuid_exist(&proc, uuid);
if (ret != 0) {
+ ret = 0;
+ log_error("Patch '%s' already exists\n", uuid);
goto out_free;
}
ret = binary_init(relf, binary_path);
if (ret) {
- log_error("Failed to load binary, ret=%d\n", ret);
+ log_error("Failed to load binary\n");
goto out_free;
}
@@ -750,24 +754,27 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
/* Finally, attach to process */
ret = upatch_process_attach(&proc);
- if (ret < 0)
+ if (ret < 0) {
+ log_error("Failed to attach process\n");
goto out_free;
+ }
// TODO: 栈解析
// 应用
ret = upatch_apply_patches(&proc, uelf, uuid);
- if (ret < 0)
+ if (ret < 0) {
+ log_error("Failed to apply patch\n");
goto out_free;
-
- ret = 0;
+ }
out_free:
upatch_process_detach(&proc);
+ gettimeofday(&end_tv, NULL);
+
upatch_process_destroy(&proc);
out:
if (is_calc_time) {
- gettimeofday(&end_tv, NULL);
frozen_time = GET_MICROSECONDS(end_tv, start_tv);
log_normal("Process %d frozen time is %ld microsecond(s)\n",
pid, frozen_time);
@@ -800,7 +807,7 @@ static int upatch_unapply_patches(struct upatch_process *proc, const char *uuid)
}
log_debug("munmap upatch layout core:\n");
- __upatch_memfree(obj,
+ upatch_free(obj,
(void *)patch->uinfo->start,
patch->uinfo->end - patch->uinfo->start
);
@@ -810,7 +817,7 @@ static int upatch_unapply_patches(struct upatch_process *proc, const char *uuid)
}
if (!found) {
- log_debug("can't found patch info memory\n");
+ log_warn("Patch '%s' is not found\n", uuid);
goto out;
}
@@ -831,16 +838,18 @@ 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("Failed to init process %d, ret=%d\n", pid, ret);
+ log_error("Failed to init process\n");
goto out;
}
- printf("Unpatch ");
+ printf("Unpatch '%s' from ", uuid);
upatch_process_print_short(&proc);
ret = upatch_process_mem_open(&proc, MEM_READ);
- if (ret < 0)
+ if (ret < 0) {
+ log_error("Failed to open process memory\n");
goto out_free;
+ }
// use uprobe to hack function. the program has been executed to the entry
// point
@@ -853,8 +862,10 @@ int process_unpatch(int pid, const char *uuid)
*/
// 解析process的mem-maps获得各个块的内存映射以及phdr
ret = upatch_process_map_object_files(&proc, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ log_error("Failed to read process memory mapping\n");
goto out_free;
+ }
is_calc_time = true;
gettimeofday(&start_tv, NULL);
@@ -862,24 +873,25 @@ int process_unpatch(int pid, const char *uuid)
/* Finally, attach to process */
ret = upatch_process_attach(&proc);
if (ret < 0) {
+ log_error("Failed to attach process\n");
goto out_free;
}
// 应用
ret = upatch_unapply_patches(&proc, uuid);
if (ret < 0) {
+ log_error("Failed to remove patch\n");
goto out_free;
}
- ret = 0;
-
out_free:
upatch_process_detach(&proc);
+ gettimeofday(&end_tv, NULL);
+
upatch_process_destroy(&proc);
out:
if (is_calc_time) {
- gettimeofday(&end_tv, NULL);
frozen_time = GET_MICROSECONDS(end_tv, start_tv);
log_normal("Process %d frozen time is %ld microsecond(s)\n",
pid, frozen_time);
@@ -924,23 +936,25 @@ int process_info(int pid)
// 查看process的信息pid: maps, mem, cmdline, exe
ret = upatch_process_init(&proc, pid);
if (ret < 0) {
- log_error("Failed to init process %d, ret=%d\n", pid, ret);
+ log_error("Failed to init process\n");
goto out;
}
ret = upatch_process_mem_open(&proc, MEM_READ);
if (ret < 0) {
+ log_error("Failed to open process memory\n");
goto out_free;
}
ret = upatch_process_map_object_files(&proc, NULL);
if (ret < 0) {
+ log_error("Failed to read process memory mapping\n");
goto out_free;
}
ret = upatch_info(&proc);
if (ret) {
- status = "active";
+ status = "actived";
}
else {
status = "removed";
diff --git a/upatch-manage/upatch-process.c b/upatch-manage/upatch-process.c
index cd3f7e0..c368165 100644
--- a/upatch-manage/upatch-process.c
+++ b/upatch-manage/upatch-process.c
@@ -57,7 +57,7 @@ static int lock_process(int pid)
fd = open(path, O_RDONLY);
if (fd < 0) {
- log_error("Failed to open '%s'\n", path);
+ log_error("Failed to open file '%s'\n", path);
return -1;
}
log_debug("OK\n");
@@ -204,7 +204,7 @@ 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("Failed to open %s", buf);
+ log_error("Failed to open file '%s'\n", buf);
return;
}
@@ -255,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("Failed to open %s", path);
+ log_error("Failed to open file '%s'\n", path);
return -1;
}
@@ -560,16 +560,9 @@ error:
int upatch_process_map_object_files(struct upatch_process *proc,
const char *patch_id)
{
- int ret;
-
- ret = upatch_process_parse_proc_maps(proc);
- if (ret < 0)
- return -1;
-
// we can get plt/got table from mem's elf_segments
// Now we read them from the running file
-
- return ret;
+ return upatch_process_parse_proc_maps(proc);
}
// static int process_has_thread_pid(struct upatch_proces *proc, int pid)
diff --git a/upatch-manage/upatch-ptrace.c b/upatch-manage/upatch-ptrace.c
index 39e8f59..1309a6e 100644
--- a/upatch-manage/upatch-ptrace.c
+++ b/upatch-manage/upatch-ptrace.c
@@ -19,6 +19,7 @@
*/
#include <errno.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
--
2.41.0

View File

@ -1,140 +0,0 @@
From ce0702b2da3820a3e872fd6563d5ce9e51cab130 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 19 Apr 2024 14:19:27 +0800
Subject: [PATCH 17/17] upatch-manage: change the way to calculate frozen time
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-manage/upatch-patch.c | 58 +++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/upatch-manage/upatch-patch.c b/upatch-manage/upatch-patch.c
index 5a8f927..ab972ac 100644
--- a/upatch-manage/upatch-patch.c
+++ b/upatch-manage/upatch-patch.c
@@ -679,6 +679,31 @@ out:
return ret;
}
+static void upatch_time_tick(int pid) {
+ static struct timeval start_tv;
+ static struct timeval end_tv;
+
+ if ((end_tv.tv_sec != 0) || (end_tv.tv_usec != 0)) {
+ memset(&start_tv, 0, sizeof(struct timeval));
+ memset(&end_tv, 0, sizeof(struct timeval));
+ }
+
+ if ((start_tv.tv_sec == 0) && (start_tv.tv_usec == 0)) {
+ gettimeofday(&start_tv, NULL);
+ } else {
+ gettimeofday(&end_tv, NULL);
+ }
+
+ if ((start_tv.tv_sec == 0) || (start_tv.tv_usec == 0) ||
+ (end_tv.tv_sec == 0) || (end_tv.tv_usec == 0)) {
+ return;
+ }
+
+ unsigned long frozen_time = GET_MICROSECONDS(end_tv, start_tv);
+ log_normal("Process %d frozen time is %ld microsecond(s)\n",
+ pid, frozen_time);
+}
+
int upatch_process_uuid_exist(struct upatch_process *proc, const char *uuid)
{
struct object_file *obj;
@@ -698,14 +723,10 @@ int upatch_process_uuid_exist(struct upatch_process *proc, const char *uuid)
int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, const char *uuid, const char *binary_path)
{
- int ret;
- bool is_calc_time = false;
- struct timeval start_tv, end_tv;
- unsigned long frozen_time;
struct upatch_process proc;
// 查看process的信息pid: maps, mem, cmdline, exe
- ret = upatch_process_init(&proc, pid);
+ int ret = upatch_process_init(&proc, pid);
if (ret < 0) {
log_error("Failed to init process\n");
goto out;
@@ -748,9 +769,7 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
}
uelf->relf = relf;
-
- is_calc_time = true;
- gettimeofday(&start_tv, NULL);
+ upatch_time_tick(pid);
/* Finally, attach to process */
ret = upatch_process_attach(&proc);
@@ -769,16 +788,11 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
out_free:
upatch_process_detach(&proc);
- gettimeofday(&end_tv, NULL);
+ upatch_time_tick(pid);
upatch_process_destroy(&proc);
out:
- if (is_calc_time) {
- frozen_time = GET_MICROSECONDS(end_tv, start_tv);
- log_normal("Process %d frozen time is %ld microsecond(s)\n",
- pid, frozen_time);
- }
return ret;
}
@@ -827,16 +841,12 @@ out:
int process_unpatch(int pid, const char *uuid)
{
- int ret;
- bool is_calc_time = false;
- struct timeval start_tv, end_tv;
- unsigned long frozen_time;
struct upatch_process proc;
// TODO: check build id
// TODO: 栈解析
// 查看process的信息pid: maps, mem, cmdline, exe
- ret = upatch_process_init(&proc, pid);
+ int ret = upatch_process_init(&proc, pid);
if (ret < 0) {
log_error("Failed to init process\n");
goto out;
@@ -867,8 +877,7 @@ int process_unpatch(int pid, const char *uuid)
goto out_free;
}
- is_calc_time = true;
- gettimeofday(&start_tv, NULL);
+ upatch_time_tick(pid);
/* Finally, attach to process */
ret = upatch_process_attach(&proc);
@@ -886,16 +895,11 @@ int process_unpatch(int pid, const char *uuid)
out_free:
upatch_process_detach(&proc);
- gettimeofday(&end_tv, NULL);
+ upatch_time_tick(pid);
upatch_process_destroy(&proc);
out:
- if (is_calc_time) {
- frozen_time = GET_MICROSECONDS(end_tv, start_tv);
- log_normal("Process %d frozen time is %ld microsecond(s)\n",
- pid, frozen_time);
- }
return ret;
}
--
2.41.0

View File

@ -1,25 +1,31 @@
#!/bin/bash -e
readonly REPO_NAME="syscare"
readonly REPO_PROVIDER="openeuler"
readonly REPO_URL="https://gitee.com/$REPO_PROVIDER/$REPO_NAME"
readonly REPO_BRANCH="openEuler-22.03"
readonly SPEC_FILE="$(find . -name '*.spec' | head -n 1)"
readonly REPO_NAME="$(basename ${SPEC_FILE} | sed 's/.spec//')"
readonly REPO_URL="https://gitee.com/openeuler/${REPO_NAME}"
readonly REPO_BRANCH="$(git branch --show-current | sed 's/-LTS.*//')"
readonly REPO_VERSION="$(grep Version ${SPEC_FILE} | head -n 1 | awk -F ' ' '{print $NF}')"
readonly PKG_NAME="${REPO_NAME}-${REPO_VERSION}"
readonly PKG_DIR="$(realpath ./${PKG_NAME})"
echo "Preparing..."
rm -rf ./${REPO_NAME} ./${PKG_NAME}
rm -f ./*.tar.gz
echo "--------------------------"
echo "Name: ${REPO_NAME}"
echo "Branch: ${REPO_BRANCH}"
echo "--------------------------"
echo "Cloning source code..."
repo_version=$(grep "Version" "$REPO_NAME.spec" | head -n 1 | awk -F ' ' '{print $NF}')
repo_dir="$REPO_NAME-$repo_version"
rm -rf "$REPO_NAME" "$repo_dir"
git clone "$REPO_URL"
echo "Prepare build requirements..."
pushd "$REPO_NAME"
echo "Checking out dest branch..."
git checkout "$REPO_BRANCH"
git clone ${REPO_URL} -b ${REPO_BRANCH} ${PKG_NAME}
echo "Vendoring dependencies..."
cargo vendor --respect-source-config --sync Cargo.toml
pushd ${PKG_DIR} > /dev/null
cargo vendor --quiet --respect-source-config --sync Cargo.toml
mkdir -p .cargo
cat << EOF > .cargo/config.toml
@ -30,14 +36,12 @@ replace-with = "vendored-sources"
directory = "vendor"
EOF
popd
popd > /dev/null
echo "Compressing package..."
mv "$REPO_NAME" "$repo_dir"
tar -czf "$repo_dir.tar.gz" "$repo_dir"
tar -czf ./${PKG_NAME}.tar.gz ${PKG_NAME}
echo "Cleaning up..."
rm -rf "$repo_dir"
rm -rf ${PKG_DIR}
echo "Done"

54
generate_patches.sh Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash -e
readonly SPEC_FILE="$(find . -name '*.spec' | head -n 1)"
readonly REPO_NAME="$(basename ${SPEC_FILE} | sed 's/.spec//')"
readonly REPO_URL="https://gitee.com/openeuler/${REPO_NAME}"
readonly REPO_BRANCH="$(git branch --show-current | sed 's/-LTS.*//')"
readonly REPO_VERSION="$(grep Version ${SPEC_FILE} | head -n 1 | awk -F ' ' '{print $NF}')"
readonly PKG_NAME="${REPO_NAME}-${REPO_VERSION}"
readonly PKG_DIR="$(realpath ./${PKG_NAME})"
readonly PATCH_DIR="$(pwd)"
echo "Preparing..."
rm -rf ${PKG_DIR}
rm -f ./*.patch
tar -xf ./${PKG_NAME}.tar.gz
pushd ${PKG_DIR} > /dev/null
readonly REPO_BASELINE="$(git rev-parse --short HEAD)"
popd > /dev/null
echo "------------------------------"
echo "Name: ${REPO_NAME}"
echo "Branch: ${REPO_BRANCH}"
echo "Baseline: ${REPO_BASELINE}"
echo "------------------------------"
echo "Syncing with remote..."
pushd ${PKG_DIR} > /dev/null
git fetch origin
popd > /dev/null
echo "Generating patches..."
# format patches
pushd ${PKG_DIR} > /dev/null
git checkout -q origin/${REPO_BRANCH}
git format-patch -qN -o ${PATCH_DIR} ${REPO_BASELINE}
popd > /dev/null
# print patch list
patch_list="$(find . -maxdepth 1 -name "*.patch" | sort)"
for patch_file in ${patch_list}; do
patch_name="$(basename ${patch_file})"
patch_id="$(echo ${patch_name} | awk -F '-' '{print $1}')"
echo "Patch${patch_id}: ${patch_name}"
done
echo "Cleaning up..."
rm -rf ${PKG_DIR}
echo "Done"

View File

@ -1,47 +1,24 @@
%define build_version %{version}-%{release}
%define kernel_devel_rpm %(echo $(rpm -q kernel-devel | head -n 1))
%define kernel_version %(echo $(rpm -q --qf "\%%{VERSION}" %{kernel_devel_rpm}))
%define kernel_name %(echo $(rpm -q --qf "\%%{VERSION}-\%%{RELEASE}.\%%{ARCH}" %{kernel_devel_rpm}))
%define pkg_kmod %{name}-kmod
%define pkg_build %{name}-build
%define build_version %{version}-%{release}
############################################
############ Package syscare ###############
############################################
Name: syscare
Version: 1.2.1
Release: 5
Version: 1.2.2
Release: 3
Summary: System hot-fix service
License: MulanPSL-2.0 and GPL-2.0-only
URL: https://gitee.com/openeuler/syscare
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-Change-uuid-type-to-Uuid.patch
Patch0005: 0005-fix-clippy-warning.patch
Patch0006: 0006-syscared-fix-cannot-find-process-of-dynlib-patch-iss.patch
Patch0007: 0007-syscared-optimize-patch-error-logic.patch
Patch0008: 0008-syscared-optimize-transaction-creation-logic.patch
Patch0009: 0009-upatch-manage-optimize-output.patch
Patch0010: 0010-syscared-optimize-patch-error-logic.patch
Patch0011: 0011-syscared-optimize-transaction-creation-logic.patch
Patch0012: 0012-common-impl-CStr-from_bytes_with_next_nul.patch
Patch0013: 0013-syscared-improve-patch-management.patch
Patch0014: 0014-syscared-stop-activating-ignored-process-on-new-proc.patch
Patch0015: 0015-syscared-adapt-upatch-manage-exit-code-change.patch
Patch0016: 0016-upatch-manage-change-exit-code.patch
Patch0017: 0017-upatch-manage-change-the-way-to-calculate-frozen-tim.patch
BuildRequires: cmake >= 3.14 make
BuildRequires: rust >= 1.51 cargo >= 1.51
BuildRequires: gcc gcc-c++
BuildRequires: kernel-devel
Requires: coreutils systemd
Requires: kpatch-runtime
Excludearch: loongarch64
############### Description ################
%description
SysCare is a system-level hot-fix service that provides security patches and system error hot-fixes for the operating system.
@ -57,9 +34,10 @@ mkdir -p build
cd build
cmake \
-DCMAKE_INSTALL_PREFIX=/usr \
-DENABLE_ASAN=0 \
-DENABLE_GCOV=0 \
-DBUILD_VERSION=%{build_version} \
-DKERNEL_VERSION=%{kernel_name} \
-DCMAKE_INSTALL_PREFIX=/usr \
..
make
@ -108,12 +86,12 @@ fi
################## Files ###################
%files
%defattr(-,root,root,-)
%defattr(-,root,root,0555)
%dir /usr/libexec/syscare
%attr(644,root,root) /usr/lib/systemd/system/syscare.service
%attr(755,root,root) /usr/bin/syscared
%attr(755,root,root) /usr/bin/syscare
%attr(755,root,root) /usr/libexec/syscare/upatch-manage
%attr(0555,root,root) /usr/bin/syscare
%attr(0550,root,root) /usr/bin/syscared
%attr(0550,root,root) /usr/libexec/syscare/upatch-manage
%attr(0550,root,root) /usr/lib/systemd/system/syscare.service
############################################
########## Package syscare-build ###########
@ -131,184 +109,21 @@ Requires: rpm rpm-build
%description build
Syscare patch building toolset.
############### PostInstall ################
%post build
systemctl daemon-reload
systemctl enable upatch
systemctl start upatch
############### PreUninstall ###############
%preun build
systemctl daemon-reload
systemctl stop upatch
systemctl disable upatch
############## PostUninstall ###############
%postun build
if [ "$1" -eq 0 ] || { [ -n "$2" ] && [ "$2" -eq 0 ]; }; then
# Remove config directory
rm -rf /etc/syscare
# Remove log directory
rm -f /var/log/syscare/upatchd_r*.log
rm -f /var/log/syscare/upatchd_r*.log.gz
if [ -z "$(ls -A /var/log/syscare)" ]; then
rm -rf /var/log/syscare
fi
# Remove run directory
rm -f /var/run/syscare/upatchd.*
if [ -z "$(ls -A /var/run/syscare)" ]; then
rm -rf /var/run/syscare
fi
fi
################## Files ###################
%files build
%defattr(-,root,root,-)
%defattr(-,root,root,0555)
%dir /usr/libexec/syscare
%attr(644,root,root) /usr/lib/systemd/system/upatch.service
%attr(755,root,root) /usr/bin/upatchd
%attr(755,root,root) /usr/libexec/syscare/syscare-build
%attr(755,root,root) /usr/libexec/syscare/upatch-build
%attr(755,root,root) /usr/libexec/syscare/upatch-diff
%attr(755,root,root) /usr/libexec/syscare/as-hijacker
%attr(755,root,root) /usr/libexec/syscare/cc-hijacker
%attr(755,root,root) /usr/libexec/syscare/c++-hijacker
%attr(755,root,root) /usr/libexec/syscare/gcc-hijacker
%attr(755,root,root) /usr/libexec/syscare/g++-hijacker
%attr(755,root,root) /usr/libexec/syscare/gnu-as-hijacker
%attr(755,root,root) /usr/libexec/syscare/gnu-compiler-hijacker
%attr(755,root,root) /usr/libexec/syscare/upatch_hijacker.ko
%attr(555,root,root) /usr/libexec/syscare/syscare-build
%attr(555,root,root) /usr/libexec/syscare/upatch-build
%attr(555,root,root) /usr/libexec/syscare/upatch-diff
%attr(555,root,root) /usr/libexec/syscare/upatch-helper
%attr(555,root,root) /usr/libexec/syscare/upatch-cc
%attr(555,root,root) /usr/libexec/syscare/upatch-c++
############################################
################ Change log ################
############################################
%changelog
* Mon May 6 2024 Peng Haitao <htpengc@isoftstone.com> - 1.2.1-5
- add BuildRequires: kernel-devel
* Fri Apr 19 2024 ningyu<ningyu9@huawei.com> - 1.2.1-4
- common: impl CStr::from_bytes_with_next_nul()
- syscared: improve patch management
- syscared: stop activating ignored process on new process start
- syscared: adapt upatch-manage exit code change
- upatch-manage: change exit code
- upatch-manage: change the way to calculate frozen time
* 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
- update to syscare.1.2.1-2
* Thu Mar 28 2024 ningyu<ningyu9@huawei.com> - 1.2.1-1
- update to 1.2.1
* Tue Dec 26 2023 ningyu<ningyu9@huawei.com> - 1.2.0-10
- fix memory leak
* Fri Dec 22 2023 ningyu<ningyu9@huawei.com> - 1.2.0-9
- Add Suggests for syscare-build
- Remove log directory
* Tue Dec 12 2023 renoseven<dev@renoseven.net> - 1.2.0-8
- Builder: fix 'enabling multiple kpatch may lead soft-lockup' issue
* Wed Nov 29 2023 renoseven<dev@renoseven.net> - 1.2.0-7
- Fix aarch64 compile issue
* Tue Nov 28 2023 renoseven<dev@renoseven.net> - 1.2.0-6
- Enable debuginfo for rust code
- Sync arguments with old version
* Tue Nov 28 2023 renoseven<dev@renoseven.net> - 1.2.0-5
- Upgrade MSRV to 1.60
- Optimize syscare build check logic
- Optimize external command calling
- Optimize log output
* Fri Nov 24 2023 renoseven<dev@renoseven.net> - 1.2.0-4
- Fix 'kpatch driver cannot support old version' issue
* Fri Nov 24 2023 renoseven<dev@renoseven.net> - 1.2.0-3
- Fix 'upatch only apply first patch for new process' issue
* Wed Nov 22 2023 renoseven<dev@renoseven.net> - 1.2.0-2
- Fix upatch process detection
* Wed Nov 22 2023 renoseven<dev@renoseven.net> - 1.2.0-1
- Fix various issue
* Wed Oct 11 2023 renoseven<dev@renoseven.net> - 1.1.0-6
- Support build patch for kernel moudules
- Fix various issue
* Fri Sep 22 2023 renoseven<dev@renoseven.net> - 1.1.0-5
- Fix various issue
* Thu Sep 21 2023 renoseven<dev@renoseven.net> - 1.1.0-4
- Fix 'syscare-build only accept one patch' issue
* Wed Sep 20 2023 renoseven<dev@renoseven.net> - 1.1.0-3
- Fix various issue
- Support MSRV 1.51
* Mon Aug 28 2023 renoseven<dev@renoseven.net> - 1.1.0-1
- Support build patch without kernel module
- Add syscare daemon
- Add syscare-build daemon
- Improve syscare cli
* Wed Jun 28 2023 renoseven<dev@renoseven.net> - 1.0.2-4
- Fix builder check failure issue
* Sun Jun 25 2023 renoseven<dev@renoseven.net> - 1.0.2-3
- Fix various issue
* Mon Jun 19 2023 renoseven<dev@renoseven.net> - 1.0.2-2
- Fix various issue
- Update dependencies
* Fri Jun 09 2023 renoseven<dev@renoseven.net> - 1.0.2-1
- Fix 'rpmpbuild getcwd failed' issue
- Fix 'upatch ko prints redundant log' issue
* Fri Jun 09 2023 renoseven<dev@renoseven.net> - 1.0.1-9
- Fix 'patch file is not checked' issue
- Rename patched source package
- Update dependencies
* Tue Jun 06 2023 renoseven<dev@renoseven.net> - 1.0.1-8
- Fix 'kernel patch sys interface collision' issue
- Fix 'patch GOT table jump fails' issue
- Fix 'patch TLS variable relocation fails' issue
* Fri Jun 02 2023 renoseven<dev@renoseven.net> - 1.0.1-7
- Various bugfix
- Support multiple compiler
* Wed May 31 2023 renoseven<dev@renoseven.net> - 1.0.1-6
- Various bugfix
- Support multiple debuginfo package
* Mon May 15 2023 renoseven<dev@renoseven.net> - 1.0.1-5
- Fix aarch64 kmod patch jump instruction error issue
- Add ifunc support
- Add 'syscare accept' command
- Add patch 'ACCEPT' state
* Tue Apr 04 2023 renoseven<dev@renoseven.net> - 1.0.1-4
- Enable aarch64
- Fix syscare-upatch service may start failed issue
* Thu Mar 30 2023 renoseven<dev@renoseven.net> - 1.0.1-3
- Fix upatch may not contain all symbols issue
- Add syscare-kmod package
* Wed Mar 29 2023 renoseven<dev@renoseven.net> - 1.0.1-2
- Fix rpm install & remove script issue
* Wed Mar 15 2023 renoseven<dev@renoseven.net> - 1.0.1-1
- New syscare cli
- Support building patch for C++ code
- Support patch version verification
- Support elf name derivation
- Support fast reboot
* Wed Dec 21 2022 snoweay<snoweay@163.com> - 1.0.0-7
- Fix 42 relocation caused by gcc 11.
* Tue Dec 20 2022 snoweay<snoweay@163.com> - 1.0.0-6
- Fix patch open failure by reading patches at attach instead of load.
- Support epoch in spec.
* Sat Dec 17 2022 snoweay<snoweay@163.com> - 1.0.0-5
- Check version-release of source pkg & debuginfo pkg.
* Fri Dec 16 2022 snoweay<snoweay@163.com> - 1.0.0-4
- Avoid duplicate elfs by not following symlinks at build.
* Thu Dec 15 2022 snoweay<snoweay@163.com> - 1.0.0-3
- Change kernel patches' scontext before apply not at rpm-post.
* Wed Dec 14 2022 snoweay<snoweay@163.com> - 1.0.0-2
- Fix some issues:
- manager: Allow apply to actived kernel patch
- build: only 'NOT-APPLIED' patch package can be removed
- build: fix 'kernel patch cannot be insmod during system start' issue
- kmod: unregister when rmmod upatch
* Tue Dec 13 2022 snoweay<snoweay@163.com> - 1.0.0-1
- Release the first version 1.0.0.
* Mon Nov 11 2024 renoseven<dev@renoseven.net> - 1.2.2-3
- syscared: support saving & restoring patch status by operation order