!222 [sync] PR-221: update syscare to 1.2.2-3

From: @openeuler-sync-bot 
Reviewed-by: @renoseven 
Signed-off-by: @renoseven
This commit is contained in:
openeuler-ci-bot 2025-02-05 01:34:49 +00:00 committed by Gitee
commit 784ca2dcb6
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
49 changed files with 13 additions and 17712 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] 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.34.1

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] 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.34.1

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] 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.34.1

View File

@ -1,686 +0,0 @@
From 32c3d16175b93627504981d05a1a3e3ec603415e Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 10 Apr 2024 19:30:56 +0800
Subject: [PATCH] syscared: fix 'cannot find process of dynlib patch' issue
1. For detecting process mapped dynamic library,
we use /proc/$pid/map_files instead.
We do readlink() to get it's real file path and then
read it's inode to judge if it's the file we want.
2. For calculating processes to be actived / deactived, we
use IndexSet::difference() / IndexSet::intersection() between
all current target process and the recorded process set.
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/patch/driver/upatch/mod.rs | 217 ++++++++++++++------
syscared/src/patch/driver/upatch/monitor.rs | 18 +-
syscared/src/patch/driver/upatch/process.rs | 126 +++++++-----
syscared/src/patch/driver/upatch/sys.rs | 108 ++++------
4 files changed, 270 insertions(+), 199 deletions(-)
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
index 98fc54c..a7fa154 100644
--- a/syscared/src/patch/driver/upatch/mod.rs
+++ b/syscared/src/patch/driver/upatch/mod.rs
@@ -21,7 +21,7 @@ use std::{
use anyhow::{ensure, Context, Result};
use indexmap::{indexset, IndexMap, IndexSet};
-use log::{debug, info};
+use log::{debug, error};
use parking_lot::Mutex;
use uuid::Uuid;
@@ -38,31 +38,31 @@ mod target;
use monitor::UserPatchMonitor;
use target::PatchTarget;
-pub(self) type ActivePatchMap = Arc<Mutex<IndexMap<PathBuf, ActivePatch>>>;
+type ElfPatchMap = Arc<Mutex<IndexMap<PathBuf, ElfPatchRecord>>>;
#[derive(Default)]
-struct ActivePatch {
- patch_list: Vec<(Uuid, PathBuf)>, // Patch applied to target elf (uuid and patch file)
- process_list: IndexSet<i32>, // Target elf process list
+struct ElfPatchRecord {
+ patch_map: IndexMap<Uuid, PathBuf>, // Patch applied to target elf (uuid and patch file)
+ processes: IndexSet<i32>, // Target elf process list
}
pub struct UserPatchDriver {
patch_target_map: IndexMap<OsString, PatchTarget>,
patch_status_map: IndexMap<Uuid, PatchStatus>,
- active_patch_map: ActivePatchMap,
+ elf_patch_map: ElfPatchMap,
patch_monitor: UserPatchMonitor,
}
impl UserPatchDriver {
pub fn new() -> Result<Self> {
- let active_patch_map = Arc::new(Mutex::new(IndexMap::new()));
+ let elf_patch_map = Arc::new(Mutex::new(IndexMap::new()));
let patch_monitor =
- UserPatchMonitor::new(active_patch_map.clone(), Self::on_new_process_created)?;
+ UserPatchMonitor::new(elf_patch_map.clone(), Self::patch_new_process)?;
let instance = Self {
patch_target_map: IndexMap::new(),
patch_status_map: IndexMap::new(),
- active_patch_map,
+ elf_patch_map,
patch_monitor,
};
Ok(instance)
@@ -168,36 +168,51 @@ impl UserPatchDriver {
}
impl UserPatchDriver {
- fn on_new_process_created(active_patch_map: ActivePatchMap, target_elf: &Path) -> Result<()> {
- // find actived patch
- if let Some(patch_record) = active_patch_map.lock().get_mut(target_elf) {
- let current_process_list = process::find_target_process(target_elf)?;
- let patched_process_list = &patch_record.process_list;
-
- // Filter patched pid
- let pid_list = current_process_list
- .iter()
- .filter(|pid| !patched_process_list.contains(*pid))
- .copied()
- .collect::<Vec<_>>();
- if pid_list.is_empty() {
- return Ok(());
- }
+ fn patch_new_process(elf_patch_map: ElfPatchMap, target_elf: &Path) {
+ let process_list = match process::find_target_process(target_elf) {
+ Ok(processes) => processes,
+ Err(_) => return,
+ };
+
+ let mut patch_map = elf_patch_map.lock();
+ let patch_record = match patch_map.get_mut(target_elf) {
+ Some(record) => record,
+ None => return,
+ };
+
+ let need_active = process_list
+ .difference(&patch_record.processes)
+ .copied()
+ .collect::<Vec<_>>();
- for (uuid, patch_file) in &patch_record.patch_list {
- info!(
- "Patching '{}' ({}) to process {:?}",
+ // Active patch
+ for (uuid, patch_file) in &patch_record.patch_map {
+ if !need_active.is_empty() {
+ debug!(
+ "Upatch: Activating patch '{}' ({}) to process {:?}",
uuid,
target_elf.display(),
- pid_list,
+ need_active,
);
- sys::active_patch(uuid, target_elf, patch_file, &pid_list)?;
}
-
- patch_record.process_list = current_process_list;
+ for pid in &need_active {
+ if let Err(e) = sys::active_patch(uuid, *pid, target_elf, patch_file) {
+ error!("{:?}", e);
+ continue;
+ }
+ patch_record.processes.insert(*pid);
+ }
}
- Ok(())
+ // Remove process no longer exists
+ let need_remove = patch_record
+ .processes
+ .difference(&process_list)
+ .copied()
+ .collect::<Vec<_>>();
+ for pid in need_remove {
+ patch_record.processes.remove(&pid);
+ }
}
}
@@ -246,7 +261,11 @@ impl UserPatchDriver {
"Upatch: Patch already exists"
);
- debug!("Upatch: Applying patch '{}'", patch_uuid);
+ debug!(
+ "Upatch: Applying patch '{}', patch_file: {}",
+ patch_uuid,
+ patch.patch_file.display()
+ );
self.patch_status_map
.insert(patch_uuid, PatchStatus::Deactived);
@@ -261,15 +280,19 @@ impl UserPatchDriver {
"Upatch: Invalid patch status"
);
- debug!("Upatch: Removing patch '{}'", patch_uuid);
+ debug!(
+ "Upatch: Removing patch '{}', patch_file: {}",
+ patch_uuid,
+ patch.patch_file.display()
+ );
self.patch_status_map.remove(&patch_uuid);
Ok(())
}
pub fn active(&mut self, patch: &UserPatch) -> Result<()> {
- let patch_uuid = patch.uuid;
- let patch_status = self.get_patch_status(patch_uuid)?;
+ let uuid = patch.uuid;
+ let patch_status = self.get_patch_status(uuid)?;
ensure!(
patch_status == PatchStatus::Deactived,
"Upatch: Invalid patch status"
@@ -277,29 +300,65 @@ impl UserPatchDriver {
let target_elf = patch.target_elf.as_path();
let patch_file = patch.patch_file.as_path();
- let pid_list = process::find_target_process(target_elf)?;
- sys::active_patch(&patch_uuid, target_elf, patch_file, &pid_list)?;
+ let process_list = process::find_target_process(target_elf)?;
+
+ let mut patch_map = self.elf_patch_map.lock();
+ let patch_record = patch_map.entry(target_elf.to_path_buf()).or_default();
+
+ let need_active = process_list
+ .difference(&patch_record.processes)
+ .copied()
+ .collect::<Vec<_>>();
+ let need_remove = patch_record
+ .processes
+ .difference(&process_list)
+ .copied()
+ .collect::<Vec<_>>();
+ let mut need_start_watch = false;
+
+ // Active patch
+ if !need_active.is_empty() {
+ debug!(
+ "Upatch: Activating patch '{}' ({}) to process {:?}",
+ uuid,
+ target_elf.display(),
+ need_active,
+ );
+ }
+ for pid in need_active {
+ if let Err(e) = sys::active_patch(&uuid, pid, target_elf, patch_file) {
+ error!("{:?}", e);
+ }
+ patch_record.processes.insert(pid);
+ }
- let mut active_patch_map = self.active_patch_map.lock();
- let active_patch = active_patch_map
- .entry(target_elf.to_path_buf())
- .or_default();
- let patch_list = &mut active_patch.patch_list;
+ // Remove process no longer exists
+ for pid in need_remove {
+ patch_record.processes.remove(&pid);
+ }
- patch_list.push((patch_uuid, patch_file.to_path_buf()));
- self.patch_monitor.watch_file(target_elf)?;
+ // If elf is not patched before, start watching it & add a new entry
+ if !patch_record.patch_map.contains_key(&uuid) {
+ patch_record
+ .patch_map
+ .insert(uuid, patch_file.to_path_buf());
+ need_start_watch = true;
+ }
- drop(active_patch_map);
+ drop(patch_map);
- self.set_patch_status(patch_uuid, PatchStatus::Actived)?;
+ if need_start_watch {
+ self.patch_monitor.watch_file(target_elf)?;
+ }
+ self.set_patch_status(uuid, PatchStatus::Actived)?;
self.add_patch_symbols(patch);
Ok(())
}
pub fn deactive(&mut self, patch: &UserPatch) -> Result<()> {
- let patch_uuid = patch.uuid;
- let patch_status = self.get_patch_status(patch_uuid)?;
+ let uuid = patch.uuid;
+ let patch_status = self.get_patch_status(uuid)?;
ensure!(
patch_status == PatchStatus::Actived,
"Upatch: Invalid patch status"
@@ -307,24 +366,58 @@ impl UserPatchDriver {
let target_elf = patch.target_elf.as_path();
let patch_file = patch.patch_file.as_path();
- let pid_list = process::find_target_process(target_elf)?;
- sys::deactive_patch(&patch_uuid, target_elf, patch_file, &pid_list)?;
+ let process_list = process::find_target_process(target_elf)?;
- let mut active_patch_map = self.active_patch_map.lock();
- let active_patch = active_patch_map
- .entry(target_elf.to_path_buf())
- .or_default();
- let patch_list = &mut active_patch.patch_list;
+ let mut patch_map = self.elf_patch_map.lock();
+ let patch_record = patch_map
+ .get_mut(target_elf)
+ .context("Failed to find elf patch record")?;
- patch_list.pop();
- if patch_list.is_empty() {
- self.patch_monitor.ignore_file(target_elf)?;
- active_patch_map.remove(target_elf);
+ let need_deactive = process_list
+ .intersection(&patch_record.processes)
+ .copied()
+ .collect::<Vec<_>>();
+ let need_removed = patch_record
+ .processes
+ .difference(&process_list)
+ .copied()
+ .collect::<Vec<_>>();
+ let mut need_stop_watch = false;
+
+ // Deactive patch
+ if !need_deactive.is_empty() {
+ debug!(
+ "Upatch: Deactivating patch '{}' ({}) of process {:?}",
+ uuid,
+ target_elf.display(),
+ need_deactive,
+ );
+ }
+ for pid in need_deactive {
+ sys::deactive_patch(&uuid, pid, target_elf, patch_file)?;
+ patch_record.processes.remove(&pid); // remove process from record
}
- drop(active_patch_map);
+ // Remove process no longer exists
+ for pid in need_removed {
+ patch_record.processes.remove(&pid);
+ }
- self.set_patch_status(patch_uuid, PatchStatus::Deactived)?;
+ // Remove patch from elf patch record
+ patch_record.patch_map.remove(&uuid);
+
+ // If elf has no more patch, stop watching it & remove the entry
+ if patch_record.patch_map.is_empty() {
+ patch_map.remove(target_elf);
+ need_stop_watch = true;
+ }
+
+ drop(patch_map);
+
+ if need_stop_watch {
+ self.patch_monitor.ignore_file(target_elf)?;
+ }
+ self.set_patch_status(uuid, PatchStatus::Deactived)?;
self.remove_patch_symbols(patch);
Ok(())
diff --git a/syscared/src/patch/driver/upatch/monitor.rs b/syscared/src/patch/driver/upatch/monitor.rs
index 0dd4088..1dbb513 100644
--- a/syscared/src/patch/driver/upatch/monitor.rs
+++ b/syscared/src/patch/driver/upatch/monitor.rs
@@ -23,10 +23,10 @@ use std::{
use anyhow::{bail, Context, Result};
use indexmap::IndexMap;
use inotify::{EventMask, Inotify, WatchDescriptor, WatchMask};
-use log::{error, info};
+use log::info;
use parking_lot::{Mutex, RwLock};
-use super::ActivePatchMap;
+use super::ElfPatchMap;
const MONITOR_THREAD_NAME: &str = "upatch_monitor";
const MONITOR_CHECK_PERIOD: u64 = 100;
@@ -40,9 +40,9 @@ pub(super) struct UserPatchMonitor {
}
impl UserPatchMonitor {
- pub fn new<F>(active_patch_map: ActivePatchMap, callback: F) -> Result<Self>
+ pub fn new<F>(elf_patch_map: ElfPatchMap, callback: F) -> Result<Self>
where
- F: Fn(ActivePatchMap, &Path) -> Result<()> + Send + 'static,
+ F: Fn(ElfPatchMap, &Path) + Send + Sync + 'static,
{
let inotify = Arc::new(Mutex::new(Some(
Inotify::init().context("Failed to initialize inotify")?,
@@ -52,7 +52,7 @@ impl UserPatchMonitor {
let monitor_thread = MonitorThread {
inotify: inotify.clone(),
target_map: target_map.clone(),
- active_patch_map,
+ elf_patch_map,
callback,
}
.run()?;
@@ -115,13 +115,13 @@ impl UserPatchMonitor {
struct MonitorThread<F> {
inotify: Arc<Mutex<Option<Inotify>>>,
target_map: Arc<RwLock<IndexMap<WatchDescriptor, PathBuf>>>,
- active_patch_map: ActivePatchMap,
+ elf_patch_map: ElfPatchMap,
callback: F,
}
impl<F> MonitorThread<F>
where
- F: Fn(ActivePatchMap, &Path) -> Result<()> + Send + 'static,
+ F: Fn(ElfPatchMap, &Path) + Send + Sync + 'static,
{
fn run(self) -> Result<thread::JoinHandle<()>> {
thread::Builder::new()
@@ -140,9 +140,7 @@ where
continue;
}
if let Some(patch_file) = self.target_map.read().get(&event.wd) {
- if let Err(e) = (self.callback)(self.active_patch_map.clone(), patch_file) {
- error!("{:?}", e);
- }
+ (self.callback)(self.elf_patch_map.clone(), patch_file);
}
}
}
diff --git a/syscared/src/patch/driver/upatch/process.rs b/syscared/src/patch/driver/upatch/process.rs
index 597fc0e..9b2f6de 100644
--- a/syscared/src/patch/driver/upatch/process.rs
+++ b/syscared/src/patch/driver/upatch/process.rs
@@ -12,77 +12,89 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{
- ffi::OsStr,
- path::{Path, PathBuf},
-};
+use std::{ffi::OsStr, os::linux::fs::MetadataExt, path::Path};
use anyhow::Result;
use indexmap::IndexSet;
use syscare_common::fs;
-use syscare_common::os::proc_maps::ProcMaps;
+const PROC_BLACK_LIST: [&str; 18] = [
+ "/usr/lib/systemd/systemd-journald",
+ "/usr/lib/systemd/systemd-logind",
+ "/usr/lib/systemd/systemd-udevd",
+ "/usr/lib/systemd/systemd-hostnamed",
+ "/usr/bin/udevadm",
+ "/usr/sbin/auditd",
+ "/usr/bin/syscare",
+ "/usr/bin/syscared",
+ "/usr/bin/upatchd",
+ "/usr/libexec/syscare/as-hijacker",
+ "/usr/libexec/syscare/cc-hijacker",
+ "/usr/libexec/syscare/c++-hijacker",
+ "/usr/libexec/syscare/gcc-hijacker",
+ "/usr/libexec/syscare/g++-hijacker",
+ "/usr/libexec/syscare/syscare-build",
+ "/usr/libexec/syscare/upatch-build",
+ "/usr/libexec/syscare/upatch-diff",
+ "/usr/libexec/syscare/upatch-manage",
+];
#[inline]
-fn parse_process_id<P: AsRef<Path>>(path: P) -> Option<i32> {
- path.as_ref()
+fn is_blacklisted(file_path: &Path) -> bool {
+ PROC_BLACK_LIST
+ .iter()
+ .map(Path::new)
+ .any(|blacklist_path| blacklist_path == file_path)
+}
+
+#[inline]
+fn parse_process_id(proc_path: &Path) -> Option<i32> {
+ proc_path
.file_name()
.and_then(OsStr::to_str)
.map(str::parse)
.and_then(Result::ok)
}
-#[inline]
-fn parse_process_path(pid: i32) -> Option<(i32, PathBuf)> {
- const PROC_BLACK_LIST: [&str; 18] = [
- "/usr/lib/systemd/systemd-journald",
- "/usr/lib/systemd/systemd-logind",
- "/usr/lib/systemd/systemd-udevd",
- "/usr/lib/systemd/systemd-hostnamed",
- "/usr/bin/udevadm",
- "/usr/sbin/auditd",
- "/usr/bin/syscare",
- "/usr/bin/syscared",
- "/usr/bin/upatchd",
- "/usr/libexec/syscare/as-hijacker",
- "/usr/libexec/syscare/cc-hijacker",
- "/usr/libexec/syscare/c++-hijacker",
- "/usr/libexec/syscare/gcc-hijacker",
- "/usr/libexec/syscare/g++-hijacker",
- "/usr/libexec/syscare/syscare-build",
- "/usr/libexec/syscare/upatch-build",
- "/usr/libexec/syscare/upatch-diff",
- "/usr/libexec/syscare/upatch-manage",
- ];
-
- fs::read_link(format!("/proc/{}/exe", pid))
- .ok()
- .filter(|path| {
- !PROC_BLACK_LIST
- .iter()
- .any(|blacklist_path| path.as_os_str() == *blacklist_path)
- })
- .map(|path| (pid, path))
-}
-
pub fn find_target_process<P: AsRef<Path>>(target_elf: P) -> Result<IndexSet<i32>> {
- let target_file = fs::canonicalize(target_elf.as_ref())?;
- let target_path = target_file.as_path();
- let target_pids = fs::list_dirs("/proc", fs::TraverseOptions { recursive: false })?
- .into_iter()
- .filter_map(self::parse_process_id)
- .filter_map(self::parse_process_path)
- .filter(|(pid, bin_path)| {
- if bin_path == target_path {
- return true;
- }
- if let Ok(mut mappings) = ProcMaps::new(*pid) {
- return mappings.any(|map| map.path_name == target_path);
- }
- false
- })
- .map(|(pid, _)| pid)
- .collect();
+ let mut target_pids = IndexSet::new();
+ let target_path = target_elf.as_ref();
+ let target_inode = target_path.metadata()?.st_ino();
+
+ for proc_path in fs::list_dirs("/proc", fs::TraverseOptions { recursive: false })? {
+ let pid = match self::parse_process_id(&proc_path) {
+ Some(pid) => pid,
+ None => continue,
+ };
+ let exec_path = match fs::read_link(format!("/proc/{}/exe", pid)) {
+ Ok(file_path) => file_path,
+ Err(_) => continue,
+ };
+ if is_blacklisted(&exec_path) {
+ continue;
+ }
+ // Try to match binary path
+ if exec_path == target_path {
+ target_pids.insert(pid);
+ continue;
+ }
+ // Try to match mapped files
+ let map_files = fs::list_symlinks(
+ format!("/proc/{}/map_files", pid),
+ fs::TraverseOptions { recursive: false },
+ )?;
+ for mapped_file in map_files {
+ if let Ok(mapped_inode) = mapped_file
+ .read_link()
+ .and_then(|file_path| Ok(file_path.metadata()?.st_ino()))
+ {
+ if mapped_inode == target_inode {
+ target_pids.insert(pid);
+ break;
+ }
+ };
+ }
+ }
Ok(target_pids)
}
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
index bab2974..f0745f0 100644
--- a/syscared/src/patch/driver/upatch/sys.rs
+++ b/syscared/src/patch/driver/upatch/sys.rs
@@ -1,7 +1,7 @@
use std::path::Path;
use anyhow::{bail, Result};
-use log::{debug, Level};
+use log::Level;
use nix::libc::EEXIST;
use uuid::Uuid;
@@ -9,80 +9,48 @@ use syscare_common::process::Command;
const UPATCH_MANAGE_BIN: &str = "/usr/libexec/syscare/upatch-manage";
-pub fn active_patch<'a, I>(
- uuid: &Uuid,
- target_elf: &Path,
- patch_file: &Path,
- pid_list: I,
-) -> Result<()>
-where
- I: IntoIterator<Item = &'a i32>,
-{
- debug!(
- "Patching '{}' to {}",
- patch_file.display(),
- target_elf.display()
- );
-
- for pid in pid_list {
- let exit_code = Command::new(UPATCH_MANAGE_BIN)
- .arg("patch")
- .arg("--uuid")
- .arg(uuid.to_string())
- .arg("--pid")
- .arg(pid.to_string())
- .arg("--binary")
- .arg(target_elf)
- .arg("--upatch")
- .arg(patch_file)
- .stdout(Level::Debug)
- .run_with_output()?
- .exit_code();
-
- match exit_code {
- 0 => {}
- EEXIST => {}
- _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
- }
+pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path) -> Result<()> {
+ let exit_code = Command::new(UPATCH_MANAGE_BIN)
+ .arg("patch")
+ .arg("--uuid")
+ .arg(uuid.to_string())
+ .arg("--pid")
+ .arg(pid.to_string())
+ .arg("--binary")
+ .arg(target_elf)
+ .arg("--upatch")
+ .arg(patch_file)
+ .stdout(Level::Debug)
+ .run_with_output()?
+ .exit_code();
+
+ match exit_code {
+ 0 => {}
+ EEXIST => {}
+ _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
}
Ok(())
}
-pub fn deactive_patch<'a, I>(
- uuid: &Uuid,
- target_elf: &Path,
- patch_file: &Path,
- pid_list: I,
-) -> Result<()>
-where
- I: IntoIterator<Item = &'a i32>,
-{
- debug!(
- "Unpatching '{}' from {}",
- patch_file.display(),
- target_elf.display()
- );
-
- for pid in pid_list {
- let exit_code = Command::new(UPATCH_MANAGE_BIN)
- .arg("unpatch")
- .arg("--uuid")
- .arg(uuid.to_string())
- .arg("--pid")
- .arg(pid.to_string())
- .arg("--binary")
- .arg(target_elf)
- .arg("--upatch")
- .arg(patch_file)
- .stdout(Level::Debug)
- .run_with_output()?
- .exit_code();
-
- match exit_code {
- 0 => {}
- _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
- }
+pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path) -> Result<()> {
+ let exit_code = Command::new(UPATCH_MANAGE_BIN)
+ .arg("unpatch")
+ .arg("--uuid")
+ .arg(uuid.to_string())
+ .arg("--pid")
+ .arg(pid.to_string())
+ .arg("--binary")
+ .arg(target_elf)
+ .arg("--upatch")
+ .arg(patch_file)
+ .stdout(Level::Debug)
+ .run_with_output()?
+ .exit_code();
+
+ match exit_code {
+ 0 => {}
+ _ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(exit_code)),
}
Ok(())
--
2.34.1

View File

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

View File

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

View File

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

View File

@ -1,47 +0,0 @@
From cc090b31139bb9aa0158e50a8a620fc41b23231c Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 16 Apr 2024 12:44:11 +0800
Subject: [PATCH] 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.34.1

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +0,0 @@
From a83410a74713c4f191aeb31bc9ea87b9e9f4bcc6 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 17 Apr 2024 19:14:19 +0800
Subject: [PATCH] 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.34.1

View File

@ -1,35 +0,0 @@
From 4ad0b0369cd039b64635d2c405fa244b6c6afb59 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 19 Apr 2024 12:02:23 +0800
Subject: [PATCH] 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.34.1

View File

@ -1,446 +0,0 @@
From e04ce4a7539a469091fef8c1566a85fe6050f728 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 19 Apr 2024 12:01:38 +0800
Subject: [PATCH] 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.34.1

View File

@ -1,140 +0,0 @@
From ff07e664cb475fa74b4f6531d8e709a5dd9b55dd Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 19 Apr 2024 14:19:27 +0800
Subject: [PATCH] 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.34.1

View File

@ -1,224 +0,0 @@
From c2fc4243ed918717bbcaa4a0c1b400051c7eded7 Mon Sep 17 00:00:00 2001
From: ningyu <ningyu9@huawei.com>
Date: Tue, 9 Apr 2024 09:21:35 +0000
Subject: [PATCH] abi: change uuid string to uuid bytes
Signed-off-by: ningyu <ningyu9@huawei.com>
---
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 | 4 +---
9 files changed, 18 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 8738225..524482e 100644
--- a/syscared/src/patch/resolver/kpatch.rs
+++ b/syscared/src/patch/resolver/kpatch.rs
@@ -15,13 +15,11 @@
use std::{
ffi::{CStr, OsString},
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::{
@@ -201,7 +199,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 985b8f1..5df11db 100644
--- a/syscared/src/patch/resolver/upatch.rs
+++ b/syscared/src/patch/resolver/upatch.rs
@@ -15,13 +15,11 @@
use std::{
ffi::{CStr, OsString},
path::Path,
- 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::CStrExt, fs};
@@ -164,7 +162,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.34.1

View File

@ -1,556 +0,0 @@
From 8deffbf247f51a8601e81bd65e448d9f228e98a8 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Thu, 9 May 2024 18:49:29 +0800
Subject: [PATCH] upatch-build: fix 'file detection cause build failure' issue
File relation detection does not work as we expected sometimes.
We changed the way to parse file relations from parsing dwarf info
to reading symlink, which is generated by hijacker.
This method would list all generated symlinks after each build,
finding the file it points to and create a file map. Because of build results
are same, we can use the symlink path as a KEY to find the relationship
between patched objects and original objects, which is the previous step for
comparing difference of each build.
Sometimes, the directory of generated objects may be different than source
directory. Thus, we provide a new argument '--object-dir', which would be
same as '--source-dir' by default.
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-build/src/args.rs | 19 ++++-
upatch-build/src/build_root.rs | 8 +-
upatch-build/src/compiler.rs | 4 +-
upatch-build/src/dwarf/mod.rs | 22 +----
upatch-build/src/file_relation.rs | 133 +++++++++++++++++-------------
upatch-build/src/main.rs | 33 ++++----
upatch-build/src/project.rs | 2 +-
upatch-build/src/rpc/remote.rs | 2 +-
8 files changed, 119 insertions(+), 104 deletions(-)
diff --git a/upatch-build/src/args.rs b/upatch-build/src/args.rs
index 9f5fa15..c3b6f48 100644
--- a/upatch-build/src/args.rs
+++ b/upatch-build/src/args.rs
@@ -23,6 +23,8 @@ use super::{CLI_ABOUT, CLI_NAME, CLI_VERSION};
const DEFAULT_WORK_DIR: &str = "/var/run/syscare";
const DEFAULT_BUILD_ROOT: &str = "./upatch";
+const DEFAULT_ELF_DIR: &str = "";
+const DEFAULT_OBJECT_DIR: &str = "";
const DEFAULT_CMD: &str = "";
const DEFAULT_COMPILERS: &str = "cc";
const DEFAULT_OUTPUT_DIR: &str = ".";
@@ -66,10 +68,14 @@ pub struct Arguments {
#[clap(short, long, multiple = true, required = true)]
pub debuginfo: Vec<PathBuf>,
- /// Specify the directory of searching elf [default: <SOURCE_DIR>]
- #[clap(long, default_value = "", hide_default_value = true)]
+ /// Specify the directory for searching elf [default: <SOURCE_DIR>]
+ #[clap(long, default_value = DEFAULT_ELF_DIR, hide_default_value = true)]
pub elf_dir: PathBuf,
+ /// Specify the directory for searching object [default: <SOURCE_DIR>]
+ #[clap(long, default_value = DEFAULT_OBJECT_DIR, hide_default_value = true)]
+ pub object_dir: PathBuf,
+
/// Specify elf's relative path relate to 'elf' or absolute patch list
#[clap(long, multiple = true, required = true)]
pub elf: Vec<PathBuf>,
@@ -111,6 +117,10 @@ impl Arguments {
false => fs::normalize(&args.elf_dir)?,
true => args.source_dir.clone(),
};
+ args.object_dir = match args.object_dir.as_os_str().is_empty() {
+ false => fs::normalize(&args.object_dir)?,
+ true => args.source_dir.clone(),
+ };
for elf_path in &mut args.elf {
*elf_path = args.elf_dir.join(&elf_path);
@@ -124,6 +134,7 @@ impl Arguments {
self.build_root = fs::normalize(self.build_root)?;
self.source_dir = fs::normalize(&self.source_dir)?;
self.elf_dir = fs::normalize(&self.elf_dir)?;
+ self.object_dir = fs::normalize(&self.object_dir)?;
self.output_dir = fs::normalize(&self.output_dir)?;
for debuginfo in &mut self.debuginfo {
@@ -149,6 +160,10 @@ impl Arguments {
self.elf_dir.is_dir(),
format!("Cannot find elf directory {}", self.elf_dir.display())
);
+ ensure!(
+ self.object_dir.is_dir(),
+ format!("Cannot find object directory {}", self.object_dir.display())
+ );
for debuginfo in &self.debuginfo {
ensure!(
debuginfo.is_file(),
diff --git a/upatch-build/src/build_root.rs b/upatch-build/src/build_root.rs
index 0d703a7..556231d 100644
--- a/upatch-build/src/build_root.rs
+++ b/upatch-build/src/build_root.rs
@@ -21,7 +21,7 @@ pub struct BuildRoot {
pub path: PathBuf,
pub original_dir: PathBuf,
pub patched_dir: PathBuf,
- pub output_dir: PathBuf,
+ pub temp_dir: PathBuf,
pub log_file: PathBuf,
}
@@ -30,19 +30,19 @@ impl BuildRoot {
let path = path.as_ref().to_path_buf();
let original_dir = path.join("original");
let patched_dir = path.join("patched");
- let output_dir = path.join("output");
+ let temp_dir = path.join("temp");
let log_file = path.join("build.log");
fs::create_dir_all(&path)?;
fs::create_dir_all(&original_dir)?;
fs::create_dir_all(&patched_dir)?;
- fs::create_dir_all(&output_dir)?;
+ fs::create_dir_all(&temp_dir)?;
Ok(Self {
path,
original_dir,
patched_dir,
- output_dir,
+ temp_dir,
log_file,
})
}
diff --git a/upatch-build/src/compiler.rs b/upatch-build/src/compiler.rs
index 9c282e2..7778f0b 100644
--- a/upatch-build/src/compiler.rs
+++ b/upatch-build/src/compiler.rs
@@ -169,7 +169,7 @@ impl Compiler {
}
impl Compiler {
- pub fn parse<I, P, Q>(compilers: I, build_dir: Q) -> Result<Vec<Compiler>>
+ pub fn parse<I, P, Q>(compilers: I, temp_dir: Q) -> Result<Vec<Compiler>>
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
@@ -183,7 +183,7 @@ impl Compiler {
.file_name()
.context("Failed to parse compiler name")?;
- let output_dir = build_dir.as_ref().join(compiler_name);
+ let output_dir = temp_dir.as_ref().join(compiler_name);
fs::create_dir_all(&output_dir)?;
debug!("- Checking {}", compiler.display());
diff --git a/upatch-build/src/dwarf/mod.rs b/upatch-build/src/dwarf/mod.rs
index aded143..35f359e 100644
--- a/upatch-build/src/dwarf/mod.rs
+++ b/upatch-build/src/dwarf/mod.rs
@@ -22,7 +22,7 @@ use std::{
path::{Path, PathBuf},
};
-use anyhow::{bail, Context, Result};
+use anyhow::{Context, Result};
use gimli::{
constants, Attribute, AttributeValue, EndianSlice, Endianity, Reader, RunTimeEndian, SectionId,
};
@@ -65,26 +65,6 @@ impl Dwarf {
Self::get_files(&object, endian)
}
- pub fn parse_source_file<P: AsRef<Path>>(object: P) -> Result<PathBuf> {
- let source_files = Dwarf::parse(&object)
- .with_context(|| format!("Failed to read dwarf of {}", object.as_ref().display()))?
- .into_iter()
- .filter_map(|dwarf| {
- let file_path = dwarf.compile_dir.join(&dwarf.file_name);
- match file_path.exists() {
- true => Some(file_path),
- false => None,
- }
- })
- .collect::<IndexSet<_>>();
-
- match source_files.len() {
- 1 => Ok(source_files[0].clone()),
- 0 => bail!("Object does not contain source file"),
- _ => bail!("Object contains to too many source files"),
- }
- }
-
pub fn parse_compiler_versions<P: AsRef<Path>>(object: P) -> Result<IndexSet<OsString>> {
let compiler_versions = Dwarf::parse(&object)
.with_context(|| format!("Failed to read dwarf of {}", object.as_ref().display()))?
diff --git a/upatch-build/src/file_relation.rs b/upatch-build/src/file_relation.rs
index ef67af1..5a58d04 100644
--- a/upatch-build/src/file_relation.rs
+++ b/upatch-build/src/file_relation.rs
@@ -21,7 +21,6 @@ use indexmap::{IndexMap, IndexSet};
use syscare_common::{ffi::OsStrExt, fs};
use super::{
- dwarf::Dwarf,
elf::{check_elf, read},
pattern_path::glob,
};
@@ -29,25 +28,32 @@ use super::{
const UPATCH_SYM_PREFIX: &str = ".upatch_";
const OBJECT_EXTENSION: &str = "o";
+/*
+ * The task of this class is to find out:
+ * 1. relationship between binary and debuginfo
+ * 2. relationship between output binaries and objects
+ * 3. relationship between original objects and patched objects
+ */
+
#[derive(Debug)]
pub struct FileRelation {
- binary_debug_map: IndexMap<PathBuf, PathBuf>, // Binary -> Debuginfo
- source_origin_map: IndexMap<PathBuf, PathBuf>, // Source file -> Original object
- binary_patched_map: IndexMap<PathBuf, IndexSet<PathBuf>>, // Binary -> Patched objects
- patched_original_map: IndexMap<PathBuf, PathBuf>, // Patched object -> Original object
+ debuginfo_map: IndexMap<PathBuf, PathBuf>, // Binary -> Debuginfo
+ symlink_map: IndexMap<PathBuf, PathBuf>, // Symlink object -> Orignal object
+ patch_objects_map: IndexMap<PathBuf, IndexSet<PathBuf>>, // Binary -> Patched objects
+ original_object_map: IndexMap<PathBuf, PathBuf>, // Patched object -> Original object
}
impl FileRelation {
pub fn new() -> Self {
Self {
- binary_debug_map: IndexMap::new(),
- binary_patched_map: IndexMap::new(),
- source_origin_map: IndexMap::new(),
- patched_original_map: IndexMap::new(),
+ debuginfo_map: IndexMap::new(),
+ symlink_map: IndexMap::new(),
+ patch_objects_map: IndexMap::new(),
+ original_object_map: IndexMap::new(),
}
}
- pub fn collect_outputs<I, J, P, Q>(&mut self, binaries: I, debuginfos: J) -> Result<()>
+ pub fn collect_debuginfo<I, J, P, Q>(&mut self, binaries: I, debuginfos: J) -> Result<()>
where
I: IntoIterator<Item = P>,
J: IntoIterator<Item = Q>,
@@ -61,86 +67,99 @@ impl FileRelation {
let binary = Self::find_binary_file(binary)?;
let debuginfo = debuginfo.as_ref().to_path_buf();
- self.binary_debug_map.insert(binary, debuginfo);
+ self.debuginfo_map.insert(binary, debuginfo);
}
Ok(())
}
- pub fn collect_original_build<P: AsRef<Path>>(&mut self, object_dir: P) -> Result<()> {
- for (binary, _) in &self.binary_debug_map {
- let upatch_ids = Self::parse_upatch_ids(binary)
- .with_context(|| format!("Failed to parse upatch id of {}", binary.display()))?;
-
- for upatch_id in upatch_ids {
- let original_object = Self::find_object_file(&object_dir, &upatch_id)
- .with_context(|| {
- format!("Failed to find object of {}", upatch_id.to_string_lossy())
- })?;
- let source_file =
- Dwarf::parse_source_file(&original_object).with_context(|| {
- format!(
- "Failed to parse source file of {}",
- original_object.display()
- )
- })?;
-
- self.source_origin_map.insert(source_file, original_object);
+ pub fn collect_original_build<P, Q>(&mut self, object_dir: P, expected_dir: Q) -> Result<()>
+ where
+ P: AsRef<Path>,
+ Q: AsRef<Path>,
+ {
+ let symlinks = fs::list_symlinks(&object_dir, fs::TraverseOptions { recursive: true })?;
+ for symlink in symlinks {
+ let object = fs::read_link(&symlink)?;
+ if !object.starts_with(expected_dir.as_ref().as_os_str()) {
+ continue;
}
+ self.symlink_map.insert(symlink, object);
}
+ ensure!(
+ !self.symlink_map.is_empty(),
+ "Cannot find any valid objects in {}",
+ object_dir.as_ref().display()
+ );
Ok(())
}
- pub fn collect_patched_build<P: AsRef<Path>>(&mut self, object_dir: P) -> Result<()> {
- for (binary, _) in &self.binary_debug_map {
+ pub fn collect_patched_build<P, Q>(&mut self, object_dir: P, expected_dir: Q) -> Result<()>
+ where
+ P: AsRef<Path>,
+ Q: AsRef<Path>,
+ {
+ let mut symlink_map = IndexMap::new();
+ let symlinks = fs::list_symlinks(&object_dir, fs::TraverseOptions { recursive: true })?;
+ for symlink in symlinks {
+ let object = fs::read_link(&symlink)?;
+ if !object.starts_with(expected_dir.as_ref().as_os_str()) {
+ continue;
+ }
+ symlink_map.insert(object, symlink);
+ }
+ ensure!(
+ !self.symlink_map.is_empty(),
+ "Cannot find any valid objects in {}",
+ object_dir.as_ref().display()
+ );
+
+ for (binary, _) in &self.debuginfo_map {
+ let mut objects = IndexSet::new();
+
let upatch_ids = Self::parse_upatch_ids(binary)
.with_context(|| format!("Failed to parse upatch id of {}", binary.display()))?;
-
- let mut patched_objects = IndexSet::new();
for upatch_id in upatch_ids {
- let patched_object =
- Self::find_object_file(&object_dir, &upatch_id).with_context(|| {
- format!("Failed to find object of {}", upatch_id.to_string_lossy())
+ let patched_object = Self::get_object_file(&expected_dir, &upatch_id)
+ .with_context(|| {
+ format!("Failed to get object of {}", upatch_id.to_string_lossy())
})?;
- let source_file = Dwarf::parse_source_file(&patched_object).with_context(|| {
- format!(
- "Failed to parse source file of {}",
- patched_object.display()
- )
- })?;
- let original_object =
- self.source_origin_map.get(&source_file).with_context(|| {
+ let original_object = symlink_map
+ .get(&patched_object)
+ .and_then(|path| self.symlink_map.get(path))
+ .with_context(|| {
format!(
- "Failed to find original object of {}",
+ "failed to find original object of {}",
patched_object.display()
)
- })?;
+ })
+ .cloned()?;
- patched_objects.insert(patched_object.clone());
- self.patched_original_map
- .insert(patched_object, original_object.to_path_buf());
+ // Update object relations
+ self.original_object_map
+ .insert(patched_object.to_owned(), original_object);
+ objects.insert(patched_object);
}
-
- self.binary_patched_map
- .insert(binary.to_path_buf(), patched_objects);
+ self.patch_objects_map.insert(binary.to_owned(), objects);
}
+ self.symlink_map.clear(); // clear useless records
Ok(())
}
pub fn get_files(&self) -> impl IntoIterator<Item = (&Path, &Path)> {
- self.binary_debug_map
+ self.debuginfo_map
.iter()
.map(|(binary, debuginfo)| (binary.as_path(), debuginfo.as_path()))
}
pub fn get_patched_objects<P: AsRef<Path>>(&self, binary: P) -> Option<&IndexSet<PathBuf>> {
- self.binary_patched_map.get(binary.as_ref())
+ self.patch_objects_map.get(binary.as_ref())
}
pub fn get_original_object<P: AsRef<Path>>(&self, object: P) -> Option<&Path> {
- self.patched_original_map
+ self.original_object_map
.get(object.as_ref())
.map(|p| p.as_path())
}
@@ -166,7 +185,7 @@ impl FileRelation {
}
}
- fn find_object_file<P, S>(object_dir: P, upatch_id: S) -> Result<PathBuf>
+ fn get_object_file<P, S>(object_dir: P, upatch_id: S) -> Result<PathBuf>
where
P: AsRef<Path>,
S: AsRef<OsStr>,
diff --git a/upatch-build/src/main.rs b/upatch-build/src/main.rs
index 99de581..b5c14a8 100644
--- a/upatch-build/src/main.rs
+++ b/upatch-build/src/main.rs
@@ -49,7 +49,7 @@ use file_relation::FileRelation;
use hijacker::Hijacker;
use project::Project;
-const CLI_NAME: &str = "syscare build";
+const CLI_NAME: &str = "upatch build";
const CLI_VERSION: &str = env!("CARGO_PKG_VERSION");
const CLI_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const CLI_UMASK: u32 = 0o022;
@@ -59,7 +59,7 @@ const LOG_FILE_NAME: &str = "build";
struct BuildInfo {
files: FileRelation,
linker: PathBuf,
- build_dir: PathBuf,
+ temp_dir: PathBuf,
output_dir: PathBuf,
verbose: bool,
}
@@ -256,11 +256,11 @@ impl UpatchBuild {
let debuginfo_name = debuginfo
.file_name()
.context("Failed to parse debuginfo name")?;
- let output_dir = build_info.build_dir.join(binary_name);
- let new_debuginfo = output_dir.join(debuginfo_name);
+ let temp_dir = build_info.temp_dir.join(binary_name);
+ let new_debuginfo = temp_dir.join(debuginfo_name);
debug!("- Preparing to build patch");
- fs::create_dir_all(&output_dir)?;
+ fs::create_dir_all(&temp_dir)?;
fs::copy(debuginfo, &new_debuginfo)?;
fs::set_permissions(&new_debuginfo, Permissions::from_mode(0o644))?;
@@ -288,7 +288,7 @@ impl UpatchBuild {
original_object,
patched_object,
&new_debuginfo,
- &output_dir,
+ &temp_dir,
build_info.verbose,
)
.with_context(|| format!("Failed to create diff objects for {}", binary.display()))?;
@@ -296,7 +296,7 @@ impl UpatchBuild {
debug!("- Collecting changes");
let mut changed_objects = fs::list_files_by_ext(
- &output_dir,
+ &temp_dir,
OBJECT_EXTENSION,
fs::TraverseOptions { recursive: false },
)?;
@@ -306,7 +306,7 @@ impl UpatchBuild {
}
debug!("- Creating patch notes");
- let notes_object = output_dir.join(NOTES_OBJECT_NAME);
+ let notes_object = temp_dir.join(NOTES_OBJECT_NAME);
Self::create_note(&new_debuginfo, &notes_object).context("Failed to create patch notes")?;
changed_objects.push(notes_object);
@@ -332,10 +332,10 @@ impl UpatchBuild {
};
let output_file = build_info.output_dir.join(&patch_name);
- info!("Generating patch {}", patch_name.to_string_lossy());
+ info!("Generating patch for '{}'", patch_name.to_string_lossy());
self.build_patch(&build_info, binary, debuginfo, &output_file)
.with_context(|| {
- format!("Failed to build patch {}", patch_name.to_string_lossy())
+ format!("Failed to build patch '{}'", patch_name.to_string_lossy())
})?;
}
@@ -346,11 +346,12 @@ impl UpatchBuild {
let work_dir = self.args.work_dir.as_path();
let name = self.args.name.as_os_str();
let output_dir = self.args.output_dir.as_path();
+ let object_dir = self.args.object_dir.as_path();
let binaries = self.args.elf.as_slice();
let debuginfos = self.args.debuginfo.as_slice();
let verbose = self.args.verbose;
- let build_dir = self.build_root.output_dir.as_path();
+ let temp_dir = self.build_root.temp_dir.as_path();
let original_dir = self.build_root.original_dir.as_path();
let patched_dir = self.build_root.patched_dir.as_path();
@@ -359,7 +360,7 @@ impl UpatchBuild {
info!("==============================");
info!("Checking compiler(s)");
- let compilers = Compiler::parse(&self.args.compiler, build_dir)?;
+ let compilers = Compiler::parse(&self.args.compiler, temp_dir)?;
let linker = compilers
.iter()
.map(|c| c.linker.clone())
@@ -406,8 +407,8 @@ impl UpatchBuild {
.with_context(|| format!("Failed to build {}", project))?;
info!("Collecting file relations");
- files.collect_outputs(binaries, debuginfos)?;
- files.collect_original_build(original_dir)?;
+ files.collect_debuginfo(binaries, debuginfos)?;
+ files.collect_original_build(object_dir, original_dir)?;
info!("Preparing {}", project);
project
@@ -425,7 +426,7 @@ impl UpatchBuild {
.with_context(|| format!("Failed to rebuild {}", project))?;
info!("Collecting file relations");
- files.collect_patched_build(patched_dir)?;
+ files.collect_patched_build(object_dir, patched_dir)?;
// Unhack compilers
drop(hijacker);
@@ -433,7 +434,7 @@ impl UpatchBuild {
let build_info = BuildInfo {
linker,
files,
- build_dir: build_dir.to_path_buf(),
+ temp_dir: temp_dir.to_path_buf(),
output_dir: output_dir.to_path_buf(),
verbose,
};
diff --git a/upatch-build/src/project.rs b/upatch-build/src/project.rs
index b2f8230..b36c26b 100644
--- a/upatch-build/src/project.rs
+++ b/upatch-build/src/project.rs
@@ -46,7 +46,7 @@ pub struct Project<'a> {
impl<'a> Project<'a> {
pub fn new(args: &'a Arguments, build_root: &'a BuildRoot) -> Self {
let root_dir = args.source_dir.as_path();
- let build_dir = build_root.output_dir.as_path();
+ let build_dir = build_root.temp_dir.as_path();
let original_dir = build_root.original_dir.as_path();
let patched_dir = build_root.patched_dir.as_path();
diff --git a/upatch-build/src/rpc/remote.rs b/upatch-build/src/rpc/remote.rs
index a34f713..9927ece 100644
--- a/upatch-build/src/rpc/remote.rs
+++ b/upatch-build/src/rpc/remote.rs
@@ -56,7 +56,7 @@ impl RpcRemote {
match error {
Error::Transport(e) => {
anyhow!(
- "Cannot connect to syscare daemon at unix://{}, {}",
+ "Cannot connect to upatch daemon at unix://{}, {}",
self.socket.display(),
e.source()
.map(|e| e.to_string())
--
2.34.1

View File

@ -1,469 +0,0 @@
From a7140a02d69b50d57403f2c769767e5365a6aa34 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Sat, 11 May 2024 08:26:33 +0800
Subject: [PATCH] upatch-diff: optimize log output
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-diff/create-diff-object.c | 177 ++++++++++++++++++-------------
upatch-diff/elf-compare.c | 2 +-
upatch-diff/elf-correlate.c | 4 +-
upatch-diff/log.h | 18 ++--
upatch-diff/running-elf.c | 6 +-
upatch-diff/running-elf.h | 6 +-
upatch-diff/upatch-elf.c | 2 +-
upatch-diff/upatch-elf.h | 4 +-
8 files changed, 122 insertions(+), 97 deletions(-)
diff --git a/upatch-diff/create-diff-object.c b/upatch-diff/create-diff-object.c
index 5dc7522..01c58b8 100644
--- a/upatch-diff/create-diff-object.c
+++ b/upatch-diff/create-diff-object.c
@@ -62,9 +62,10 @@
#define PROG_VERSION "upatch-diff "BUILD_VERSION
-enum loglevel loglevel = NORMAL;
-char *logprefix;
-char *upatch_elf_name;
+enum LogLevel g_loglevel = NORMAL;
+char *g_logprefix;
+char *g_uelf_name;
+char *g_relf_name;
struct arguments {
char *source_obj;
@@ -334,72 +335,87 @@ enum LOCAL_MATCH {
EMPTY,
};
-static enum LOCAL_MATCH locals_match(struct running_elf *relf, int idx,
- struct symbol *file_sym, struct list_head *sym_list)
+static enum LOCAL_MATCH locals_match(
+ struct upatch_elf *uelf, struct running_elf *relf,
+ struct symbol *file_sym, int file_sym_idx)
{
- struct symbol *sym;
- struct object_symbol *running_sym;
- int i;
+ struct symbol *uelf_sym = NULL;
+ struct debug_symbol *relf_sym = NULL;
enum LOCAL_MATCH found = EMPTY;
- for (i = idx + 1; i < relf->obj_nr; ++i) {
- running_sym = &relf->obj_syms[i];
- if (running_sym->type == STT_FILE)
- break;
- if (running_sym->bind != STB_LOCAL)
+ for (int i = file_sym_idx + 1; i < relf->obj_nr; i++) {
+ relf_sym = &relf->obj_syms[i];
+
+ if (relf_sym->type == STT_FILE) {
+ break; // find until next file
+ }
+ if (relf_sym->bind != STB_LOCAL) {
continue;
- if (running_sym->type != STT_FUNC && running_sym->type != STT_OBJECT)
+ }
+ if ((relf_sym->type != STT_FUNC) &&
+ (relf_sym->type != STT_OBJECT)) {
continue;
+ }
found = NOT_FOUND;
- sym = file_sym;
- list_for_each_entry_continue(sym, sym_list, list) {
- if (sym->type == STT_FILE)
- break;
- if(sym->bind != STB_LOCAL)
+ uelf_sym = file_sym;
+ list_for_each_entry_continue(uelf_sym, &uelf->symbols, list) {
+ if (uelf_sym->type == STT_FILE) {
+ break; // find until next file
+ }
+ if(uelf_sym->bind != STB_LOCAL) {
continue;
-
- if (sym->type == running_sym->type &&
- !strcmp(sym->name, running_sym->name)) {
- found = FOUND;
- break;
+ }
+ if ((uelf_sym->type == relf_sym->type) &&
+ (strcmp(uelf_sym->name, relf_sym->name) == 0)) {
+ found = FOUND;
+ break;
}
}
if (found == NOT_FOUND) {
- log_warn("Cannot find symbol '%s' in running binary\n", running_sym->name);
+ log_warn("Cannot find symbol '%s' in %s\n",
+ relf_sym->name, g_relf_name);
return NOT_FOUND;
}
}
- sym = file_sym;
- list_for_each_entry_continue(sym, sym_list, list) {
- if (sym->type == STT_FILE)
- break;
- if(sym->bind != STB_LOCAL)
+ uelf_sym = file_sym;
+ list_for_each_entry_continue(uelf_sym, &uelf->symbols, list) {
+ if (uelf_sym->type == STT_FILE) {
+ break; // find until next file
+ }
+ if(uelf_sym->bind != STB_LOCAL) {
continue;
- if (sym->type != STT_FUNC && sym->type != STT_OBJECT)
+ }
+ if ((relf_sym->type != STT_FUNC) &&
+ (relf_sym->type != STT_OBJECT)) {
continue;
- if (discarded_sym(relf, sym))
+ }
+ if (discarded_sym(relf, uelf_sym)) {
continue;
+ }
found = NOT_FOUND;
- for (i = idx + 1; i < relf->obj_nr; ++i) {
- running_sym = &relf->obj_syms[i];
- if (running_sym->type == STT_FILE)
- break;
- if (running_sym->bind != STB_LOCAL)
- continue;
+ for (int i = file_sym_idx + 1; i < relf->obj_nr; i++) {
+ relf_sym = &relf->obj_syms[i];
- if (sym->type == running_sym->type &&
- !strcmp(sym->name, running_sym->name)) {
- found = FOUND;
- break;
+ if (relf_sym->type == STT_FILE) {
+ break; // find until next file
+ }
+ if (relf_sym->bind != STB_LOCAL) {
+ continue;
+ }
+ if ((uelf_sym->type == relf_sym->type) &&
+ (strcmp(uelf_sym->name, relf_sym->name) == 0)) {
+ found = FOUND;
+ break;
}
}
- if (found == NOT_FOUND){
- log_warn("Cannot find symbol '%s' in object\n", sym->name);
+ if (found == NOT_FOUND) {
+ log_warn("Cannot find symbol '%s' in %s\n",
+ uelf_sym->name, g_uelf_name);
return NOT_FOUND;
}
}
@@ -407,41 +423,48 @@ static enum LOCAL_MATCH locals_match(struct running_elf *relf, int idx,
return found;
}
-static void find_local_syms(struct running_elf *relf, struct symbol *file_sym,
- struct list_head *sym_list)
+static void find_local_syms(struct upatch_elf *uelf, struct running_elf *relf,
+ struct symbol *file_sym)
{
- struct object_symbol *running_sym;
- struct object_symbol *lookup_running_file_sym = NULL;
- int i;
+ struct debug_symbol *relf_sym = NULL;
+ struct debug_symbol *found_sym = NULL;
enum LOCAL_MATCH found;
- for (i = 0; i < relf->obj_nr; ++i) {
- running_sym = &relf->obj_syms[i];
- if (running_sym->type != STT_FILE)
+ for (int i = 0; i < relf->obj_nr; i++) {
+ relf_sym = &relf->obj_syms[i];
+
+ if (relf_sym->type != STT_FILE) {
continue;
- if (strcmp(file_sym->name, running_sym->name))
+ }
+ if (strcmp(file_sym->name, relf_sym->name)) {
continue;
- found = locals_match(relf, i, file_sym, sym_list);
+ }
+
+ found = locals_match(uelf, relf, file_sym, i);
if (found == NOT_FOUND) {
continue;
- } else if (found == EMPTY) {
- lookup_running_file_sym = running_sym;
+ }
+ else if (found == EMPTY) {
+ found_sym = relf_sym;
break;
- } else {
- if (lookup_running_file_sym)
- ERROR("Found duplicate local symbols in '%s'", file_sym->name);
-
- lookup_running_file_sym = running_sym;
+ }
+ else {
+ if (found_sym) {
+ ERROR("Found duplicate local symbols in '%s'", g_relf_name);
+ }
+ found_sym = relf_sym;
}
}
- if (!lookup_running_file_sym)
- ERROR("Cannot find a local symbol in '%s'", file_sym->name);
+ if (!found_sym) {
+ ERROR("Cannot find local symbol in '%s'", g_relf_name);
+ }
- list_for_each_entry_continue(file_sym, sym_list, list) {
- if (file_sym->type == STT_FILE)
+ list_for_each_entry_continue(file_sym, &uelf->symbols, list) {
+ if (file_sym->type == STT_FILE) {
break;
- file_sym->lookup_running_file_sym = lookup_running_file_sym;
+ }
+ file_sym->relf_sym = found_sym;
}
}
@@ -453,13 +476,14 @@ static void find_local_syms(struct running_elf *relf, struct symbol *file_sym,
* We then compare local symbol lists from both blocks and store the pointer
* to STT_FILE symbol in running elf for later using.
*/
-static void find_file_symbol(struct upatch_elf *uelf, struct running_elf *relf)
+static void find_debug_symbol(struct upatch_elf *uelf, struct running_elf *relf)
{
- struct symbol *sym;
+ struct symbol *file_sym = NULL;
- list_for_each_entry(sym, &uelf->symbols, list) {
- if (sym->type == STT_FILE)
- find_local_syms(relf, sym, &uelf->symbols);
+ list_for_each_entry(file_sym, &uelf->symbols, list) {
+ if (file_sym->type == STT_FILE) {
+ find_local_syms(uelf, relf, file_sym);
+ }
}
}
@@ -735,7 +759,7 @@ static int include_changed_functions(struct upatch_elf *uelf)
if (sym->status == CHANGED &&
sym->type == STT_SECTION &&
sym->sec && is_except_section(sym->sec)) {
- log_warn("Exeception section '%s' is changed\n", sym->sec->name);
+ log_warn("Exception section '%s' is changed\n", sym->sec->name);
changed_nr++;
include_symbol(sym);
}
@@ -886,15 +910,16 @@ int main(int argc, char*argv[])
argp_parse(&argp, argc, argv, 0, NULL, &arguments);
if (arguments.debug)
- loglevel = DEBUG;
- logprefix = basename(arguments.source_obj);
+ g_loglevel = DEBUG;
+ g_logprefix = basename(arguments.source_obj);
show_program_info(&arguments);
if (elf_version(EV_CURRENT) == EV_NONE)
ERROR("ELF library initialization failed");
/* TODO: with debug info, this may changed */
- upatch_elf_name = arguments.running_elf;
+ g_uelf_name = arguments.source_obj;
+ g_relf_name = arguments.running_elf;
/* check error in log, since errno may be from libelf */
upatch_elf_open(&uelf_source, arguments.source_obj);
@@ -912,7 +937,7 @@ int main(int argc, char*argv[])
detect_child_functions(&uelf_source);
detect_child_functions(&uelf_patched);
- find_file_symbol(&uelf_source, &relf);
+ find_debug_symbol(&uelf_source, &relf);
mark_grouped_sections(&uelf_patched);
diff --git a/upatch-diff/elf-compare.c b/upatch-diff/elf-compare.c
index 054f16a..9b857b1 100644
--- a/upatch-diff/elf-compare.c
+++ b/upatch-diff/elf-compare.c
@@ -177,7 +177,7 @@ bool upatch_handle_redis_line(const char *symname)
/* TODO: let user support this list or generate by the compiler ? */
bool check_line_func(struct upatch_elf *uelf, const char *symname)
{
- if (!strncmp(basename(upatch_elf_name), "redis-server", 12))
+ if (!strncmp(basename(g_relf_name), "redis-server", 12))
return upatch_handle_redis_line(symname);
return false;
diff --git a/upatch-diff/elf-correlate.c b/upatch-diff/elf-correlate.c
index f25f252..a0fe669 100644
--- a/upatch-diff/elf-correlate.c
+++ b/upatch-diff/elf-correlate.c
@@ -40,8 +40,8 @@ static void correlate_symbol(struct symbol *sym_orig, struct symbol *sym_patched
if (!sym_patched->name)
ERROR("strdup");
}
- if (sym_orig->lookup_running_file_sym && !sym_patched->lookup_running_file_sym)
- sym_patched->lookup_running_file_sym = sym_orig->lookup_running_file_sym;
+ if (sym_orig->relf_sym && !sym_patched->relf_sym)
+ sym_patched->relf_sym = sym_orig->relf_sym;
}
void upatch_correlate_symbols(struct upatch_elf *uelf_source, struct upatch_elf *uelf_patched)
diff --git a/upatch-diff/log.h b/upatch-diff/log.h
index 5af3e34..34b58bf 100644
--- a/upatch-diff/log.h
+++ b/upatch-diff/log.h
@@ -28,9 +28,9 @@
#include <stdio.h>
#include <error.h>
-/* Files that include log.h must define loglevel and logprefix */
-extern enum loglevel loglevel;
-extern char *logprefix;
+/* Files that include log.h must define g_loglevel and g_logprefix */
+extern enum LogLevel g_loglevel;
+extern char *g_logprefix;
enum exit_status{
EXIT_STATUS_SUCCESS = 0,
@@ -41,19 +41,19 @@ enum exit_status{
/* Since upatch-build is an one-shot program, we do not care about failure handler */
#define ERROR(format, ...) \
- error(EXIT_STATUS_ERROR, 0, "ERROR: %s: %s: %d: " format, logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__)
+ error(EXIT_STATUS_ERROR, 0, "ERROR: %s: %s: %d: " format, g_logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DIFF_FATAL(format, ...) \
- error(EXIT_STATUS_DIFF_FATAL, 0, "ERROR: %s: %s: %d: " format, logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__)
+ error(EXIT_STATUS_DIFF_FATAL, 0, "ERROR: %s: %s: %d: " format, g_logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__)
/* it is time cost */
#define log_debug(format, ...) log(DEBUG, format, ##__VA_ARGS__)
-#define log_normal(format, ...) log(NORMAL, "%s: " format, logprefix, ##__VA_ARGS__)
-#define log_warn(format, ...) log(WARN, "%s: " format, logprefix, ##__VA_ARGS__)
+#define log_normal(format, ...) log(NORMAL, "%s: " format, g_logprefix, ##__VA_ARGS__)
+#define log_warn(format, ...) log(WARN, "%s: " format, g_logprefix, ##__VA_ARGS__)
#define log(level, format, ...) \
({ \
- if (loglevel <= (level)) \
+ if (g_loglevel <= (level)) \
printf(format, ##__VA_ARGS__); \
})
@@ -63,7 +63,7 @@ enum exit_status{
ERROR(message); \
while (0)
-enum loglevel {
+enum LogLevel {
DEBUG,
NORMAL,
WARN,
diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c
index e190691..037f5fc 100644
--- a/upatch-diff/running-elf.c
+++ b/upatch-diff/running-elf.c
@@ -84,7 +84,7 @@ void relf_init(char *elf_name, struct running_elf *relf)
ERROR("elf_getdata with error %s", elf_errmsg(0));
relf->obj_nr = shdr.sh_size / shdr.sh_entsize;
- relf->obj_syms = calloc(relf->obj_nr, sizeof(struct object_symbol));
+ relf->obj_syms = calloc(relf->obj_nr, sizeof(struct debug_symbol));
if (!relf->obj_syms)
ERROR("calloc with errno = %d", errno);
@@ -117,7 +117,7 @@ bool lookup_relf(struct running_elf *relf, struct symbol *lookup_sym,
struct lookup_result *result)
{
int i;
- struct object_symbol *sym;
+ struct debug_symbol *sym;
unsigned long sympos = 0;
bool in_file = false;
@@ -128,7 +128,7 @@ bool lookup_relf(struct running_elf *relf, struct symbol *lookup_sym,
if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name))
sympos ++;
- if (lookup_sym->lookup_running_file_sym == sym) {
+ if (lookup_sym->relf_sym == sym) {
in_file = true;
continue;
}
diff --git a/upatch-diff/running-elf.h b/upatch-diff/running-elf.h
index 0eb5c70..0646780 100644
--- a/upatch-diff/running-elf.h
+++ b/upatch-diff/running-elf.h
@@ -35,12 +35,12 @@
struct symbol;
struct lookup_result {
- struct object_symbol *symbol;
+ struct debug_symbol *symbol;
unsigned long sympos;
bool global;
};
-struct object_symbol {
+struct debug_symbol {
char *name;
unsigned char type, bind;
unsigned int shndx;
@@ -50,7 +50,7 @@ struct object_symbol {
struct running_elf {
int obj_nr;
- struct object_symbol *obj_syms;
+ struct debug_symbol *obj_syms;
int fd;
Elf *elf;
bool is_exec;
diff --git a/upatch-diff/upatch-elf.c b/upatch-diff/upatch-elf.c
index e39fb6a..fc4396a 100644
--- a/upatch-diff/upatch-elf.c
+++ b/upatch-diff/upatch-elf.c
@@ -206,7 +206,7 @@ static void create_rela_list(struct upatch_elf *uelf, struct section *relasec)
if (skip)
continue;
- log_debug("offset %d, type %d, %s %s %ld \n", rela->offset,
+ log_debug("offset %d, type %d, %s %s %ld", rela->offset,
rela->type, rela->sym->name,
(rela->addend < 0) ? "-" : "+", labs(rela->addend));
if (rela->string) // rela->string is not utf8
diff --git a/upatch-diff/upatch-elf.h b/upatch-diff/upatch-elf.h
index 2f7c777..b2d038b 100644
--- a/upatch-diff/upatch-elf.h
+++ b/upatch-diff/upatch-elf.h
@@ -32,7 +32,7 @@
#include "list.h"
#include "running-elf.h"
-extern char *upatch_elf_name;
+extern char *g_relf_name;
// these data structs contain each other
struct section;
@@ -102,7 +102,7 @@ struct symbol {
struct section *sec;
GElf_Sym sym;
char *name;
- struct object_symbol *lookup_running_file_sym;
+ struct debug_symbol *relf_sym;
unsigned int index;
unsigned char bind;
unsigned char type;
--
2.34.1

View File

@ -1,99 +0,0 @@
From b43d59716bb5ae6811c3f4fcab33ca9a6704b175 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Sat, 11 May 2024 08:28:48 +0800
Subject: [PATCH] security: change directory permission
1. config_dir /etc/syscare drwx------.
2. data_dir /usr/lib/syscare drwx------.
3. log_dir /var/log/syscare drwx------.
4. work_dir /var/run/syscare drwxr-xr-x.
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/main.rs | 9 +++++++--
upatchd/src/args.rs | 2 +-
upatchd/src/main.rs | 13 +++++++++----
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/syscared/src/main.rs b/syscared/src/main.rs
index 74bd488..22f01df 100644
--- a/syscared/src/main.rs
+++ b/syscared/src/main.rs
@@ -47,7 +47,9 @@ const DAEMON_VERSION: &str = env!("CARGO_PKG_VERSION");
const DAEMON_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const DAEMON_UMASK: u32 = 0o077;
-const WORK_DIR_PERMISSION: u32 = 0o755;
+const DATA_DIR_PERM: u32 = 0o700;
+const WORK_DIR_PERM: u32 = 0o755;
+const LOG_DIR_PERM: u32 = 0o700;
const PID_FILE_NAME: &str = "syscared.pid";
const SOCKET_FILE_NAME: &str = "syscared.sock";
@@ -102,7 +104,10 @@ impl SyscareDaemon {
fs::create_dir_all(&args.data_dir)?;
fs::create_dir_all(&args.work_dir)?;
fs::create_dir_all(&args.log_dir)?;
- fs::set_permissions(&args.work_dir, Permissions::from_mode(WORK_DIR_PERMISSION))?;
+ fs::set_permissions(&args.data_dir, Permissions::from_mode(DATA_DIR_PERM))?;
+ fs::set_permissions(&args.work_dir, Permissions::from_mode(WORK_DIR_PERM))?;
+ fs::set_permissions(&args.log_dir, Permissions::from_mode(LOG_DIR_PERM))?;
+
std::env::set_current_dir(&args.work_dir).with_context(|| {
format!(
"Failed to change current directory to {}",
diff --git a/upatchd/src/args.rs b/upatchd/src/args.rs
index 9311047..0b9029b 100644
--- a/upatchd/src/args.rs
+++ b/upatchd/src/args.rs
@@ -22,8 +22,8 @@ use syscare_common::fs;
use super::{DAEMON_ABOUT, DAEMON_NAME, DAEMON_VERSION};
-const DEFAULT_WORK_DIR: &str = "/var/run/syscare";
const DEFAULT_CONFIG_DIR: &str = "/etc/syscare";
+const DEFAULT_WORK_DIR: &str = "/var/run/syscare";
const DEFAULT_LOG_DIR: &str = "/var/log/syscare";
const DEFAULT_LOG_LEVEL: &str = "info";
diff --git a/upatchd/src/main.rs b/upatchd/src/main.rs
index 86e2052..1007ebb 100644
--- a/upatchd/src/main.rs
+++ b/upatchd/src/main.rs
@@ -43,8 +43,10 @@ const CONFIG_FILE_NAME: &str = "upatchd.yaml";
const PID_FILE_NAME: &str = "upatchd.pid";
const SOCKET_FILE_NAME: &str = "upatchd.sock";
-const WORK_DIR_PERMISSION: u32 = 0o755;
-const SOCKET_FILE_PERMISSION: u32 = 0o666;
+const CONFIG_DIR_PERM: u32 = 0o700;
+const WORK_DIR_PERM: u32 = 0o755;
+const LOG_DIR_PERM: u32 = 0o700;
+const SOCKET_FILE_PERM: u32 = 0o666;
const MAIN_THREAD_NAME: &str = "main";
const UNNAMED_THREAD_NAME: &str = "<unnamed>";
@@ -97,7 +99,10 @@ impl UpatchDaemon {
fs::create_dir_all(&args.config_dir)?;
fs::create_dir_all(&args.work_dir)?;
fs::create_dir_all(&args.log_dir)?;
- fs::set_permissions(&args.work_dir, Permissions::from_mode(WORK_DIR_PERMISSION))?;
+ fs::set_permissions(&args.config_dir, Permissions::from_mode(CONFIG_DIR_PERM))?;
+ fs::set_permissions(&args.work_dir, Permissions::from_mode(WORK_DIR_PERM))?;
+ fs::set_permissions(&args.log_dir, Permissions::from_mode(LOG_DIR_PERM))?;
+
std::env::set_current_dir(&args.work_dir).with_context(|| {
format!(
"Failed to change current directory to {}",
@@ -168,7 +173,7 @@ impl UpatchDaemon {
.context("Failed to convert socket path to string")?,
)?;
- fs::set_permissions(&socket_file, Permissions::from_mode(SOCKET_FILE_PERMISSION))?;
+ fs::set_permissions(&socket_file, Permissions::from_mode(SOCKET_FILE_PERM))?;
Ok(server)
}
--
2.34.1

View File

@ -1,826 +0,0 @@
From bbbcb0c08f4a6a63230288485d88492465e2a593 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Sat, 11 May 2024 10:21:58 +0800
Subject: [PATCH] security: change daemon socket permission
1. add socket uid & gid to config file
default uid: 0
default gid: 0
2. set socket permission by its uid & gid
uid == gid: 0600
uid != gid: 0660
Signed-off-by: renoseven <dev@renoseven.net>
---
Cargo.lock | 2 +
syscared/Cargo.toml | 1 +
syscared/src/args.rs | 8 ++-
syscared/src/config.rs | 88 ++++++++++++++++++++++++++++++
syscared/src/main.rs | 70 ++++++++++++++++++------
upatchd/Cargo.toml | 2 +-
upatchd/src/config.rs | 91 ++++++++++++++++++++++++++++++++
upatchd/src/hijacker/config.rs | 85 +++++------------------------
upatchd/src/hijacker/mod.rs | 47 +++--------------
upatchd/src/main.rs | 55 ++++++++++++++-----
upatchd/src/rpc/skeleton_impl.rs | 8 +--
11 files changed, 310 insertions(+), 147 deletions(-)
create mode 100644 syscared/src/config.rs
create mode 100644 upatchd/src/config.rs
diff --git a/Cargo.lock b/Cargo.lock
index e6d830b..e3074a6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -511,6 +511,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
+ "serde",
]
[[package]]
@@ -1185,6 +1186,7 @@ dependencies = [
"object",
"parking_lot",
"serde",
+ "serde_yaml",
"signal-hook",
"syscare-abi",
"syscare-common",
diff --git a/syscared/Cargo.toml b/syscared/Cargo.toml
index 2b148e7..27f27e2 100644
--- a/syscared/Cargo.toml
+++ b/syscared/Cargo.toml
@@ -26,5 +26,6 @@ nix = { version = "0.26" }
object = { version = "0.29" }
parking_lot = { version = "0.11" }
serde = { version = "1.0", features = ["derive"] }
+serde_yaml = { version = "0.8" }
signal-hook = { version = "0.3" }
uuid = { version = "0.8", features = ["v4", "serde"] }
diff --git a/syscared/src/args.rs b/syscared/src/args.rs
index 71cdf95..4c28dff 100644
--- a/syscared/src/args.rs
+++ b/syscared/src/args.rs
@@ -22,6 +22,7 @@ use syscare_common::fs;
use super::{DAEMON_ABOUT, DAEMON_NAME, DAEMON_VERSION};
+const DEFAULT_CONFIG_DIR: &str = "/etc/syscare";
const DEFAULT_DATA_ROOT: &str = "/usr/lib/syscare";
const DEFAULT_WORK_DIR: &str = "/var/run/syscare";
const DEFAULT_LOG_DIR: &str = "/var/log/syscare";
@@ -42,6 +43,10 @@ pub struct Arguments {
#[clap(short, long)]
pub daemon: bool,
+ /// Daemon config directory
+ #[clap(long, default_value=DEFAULT_CONFIG_DIR)]
+ pub config_dir: PathBuf,
+
/// Daemon data directory
#[clap(long, default_value = DEFAULT_DATA_ROOT)]
pub data_dir: PathBuf,
@@ -65,8 +70,9 @@ impl Arguments {
}
fn normalize_path(mut self) -> Result<Self> {
- self.work_dir = fs::normalize(&self.work_dir)?;
+ self.config_dir = fs::normalize(&self.config_dir)?;
self.data_dir = fs::normalize(&self.data_dir)?;
+ self.work_dir = fs::normalize(&self.work_dir)?;
self.log_dir = fs::normalize(&self.log_dir)?;
Ok(self)
diff --git a/syscared/src/config.rs b/syscared/src/config.rs
new file mode 100644
index 0000000..af98a51
--- /dev/null
+++ b/syscared/src/config.rs
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: Mulan PSL v2
+/*
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ * upatchd is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ *
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+use std::path::Path;
+
+use anyhow::{anyhow, Result};
+use serde::{Deserialize, Serialize};
+use syscare_common::fs;
+
+const DEFAULT_SOCKET_UID: u32 = 0;
+const DEFAULT_SOCKET_GID: u32 = 0;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct SocketConfig {
+ pub uid: u32,
+ pub gid: u32,
+}
+
+impl Default for SocketConfig {
+ fn default() -> Self {
+ Self {
+ uid: DEFAULT_SOCKET_UID,
+ gid: DEFAULT_SOCKET_GID,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct DaemonConfig {
+ pub socket: SocketConfig,
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Config {
+ pub daemon: DaemonConfig,
+}
+
+impl Config {
+ pub fn parse<P: AsRef<Path>>(path: P) -> Result<Self> {
+ let config_path = path.as_ref();
+ let instance = serde_yaml::from_reader(fs::open_file(config_path)?)
+ .map_err(|_| anyhow!("Failed to parse config {}", config_path.display()))?;
+
+ Ok(instance)
+ }
+
+ pub fn write<P: AsRef<Path>>(&self, path: P) -> Result<()> {
+ let config_path = path.as_ref();
+ let config_file = fs::create_file(config_path)?;
+ serde_yaml::to_writer(config_file, self)
+ .map_err(|_| anyhow!("Failed to write config {}", config_path.display()))?;
+
+ Ok(())
+ }
+}
+
+#[test]
+fn test() -> Result<()> {
+ use anyhow::{ensure, Context};
+ use std::path::PathBuf;
+
+ let tmp_file = PathBuf::from("/tmp/syscared.yaml");
+
+ let orig_cfg = Config::default();
+ println!("{:#?}", orig_cfg);
+
+ orig_cfg
+ .write(&tmp_file)
+ .context("Failed to write config")?;
+
+ let new_cfg = Config::parse(tmp_file).context("Failed to read config")?;
+ println!("{:#?}", new_cfg);
+
+ ensure!(orig_cfg == new_cfg, "Config does not match");
+
+ Ok(())
+}
diff --git a/syscared/src/main.rs b/syscared/src/main.rs
index 22f01df..b840abf 100644
--- a/syscared/src/main.rs
+++ b/syscared/src/main.rs
@@ -22,7 +22,8 @@ use flexi_logger::{
};
use jsonrpc_core::IoHandler;
use jsonrpc_ipc_server::{Server, ServerBuilder};
-use log::{error, info, LevelFilter, Record};
+use log::{debug, error, info, warn, LevelFilter, Record};
+use nix::unistd::{chown, Gid, Uid};
use parking_lot::RwLock;
use patch::manager::PatchManager;
use signal_hook::{consts::TERM_SIGNALS, iterator::Signals, low_level::signal_name};
@@ -30,38 +31,45 @@ use signal_hook::{consts::TERM_SIGNALS, iterator::Signals, low_level::signal_nam
use syscare_common::{fs, os};
mod args;
+mod config;
mod fast_reboot;
mod patch;
mod rpc;
use args::Arguments;
+use config::Config;
+use patch::monitor::PatchMonitor;
use rpc::{
skeleton::{FastRebootSkeleton, PatchSkeleton},
skeleton_impl::{FastRebootSkeletonImpl, PatchSkeletonImpl},
};
-use crate::patch::monitor::PatchMonitor;
-
const DAEMON_NAME: &str = env!("CARGO_PKG_NAME");
const DAEMON_VERSION: &str = env!("CARGO_PKG_VERSION");
const DAEMON_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const DAEMON_UMASK: u32 = 0o077;
+const CONFIG_FILE_NAME: &str = "syscared.yaml";
+const PID_FILE_NAME: &str = "syscared.pid";
+const SOCKET_FILE_NAME: &str = "syscared.sock";
+
+const CONFIG_DIR_PERM: u32 = 0o700;
const DATA_DIR_PERM: u32 = 0o700;
const WORK_DIR_PERM: u32 = 0o755;
const LOG_DIR_PERM: u32 = 0o700;
-const PID_FILE_NAME: &str = "syscared.pid";
-const SOCKET_FILE_NAME: &str = "syscared.sock";
+const SOCKET_FILE_PERM: u32 = 0o660;
+const SOCKET_FILE_PERM_STRICT: u32 = 0o600;
const MAIN_THREAD_NAME: &str = "main";
const UNNAMED_THREAD_NAME: &str = "<unnamed>";
const LOG_FORMAT: &str = "%Y-%m-%d %H:%M:%S%.6f";
-struct SyscareDaemon {
+struct Daemon {
args: Arguments,
+ config: Config,
}
-impl SyscareDaemon {
+impl Daemon {
fn format_log(
w: &mut dyn std::io::Write,
now: &mut DeferredNow,
@@ -101,9 +109,11 @@ impl SyscareDaemon {
os::umask::set_umask(DAEMON_UMASK);
let args = Arguments::new()?;
+ fs::create_dir_all(&args.config_dir)?;
fs::create_dir_all(&args.data_dir)?;
fs::create_dir_all(&args.work_dir)?;
fs::create_dir_all(&args.log_dir)?;
+ fs::set_permissions(&args.config_dir, Permissions::from_mode(CONFIG_DIR_PERM))?;
fs::set_permissions(&args.data_dir, Permissions::from_mode(DATA_DIR_PERM))?;
fs::set_permissions(&args.work_dir, Permissions::from_mode(WORK_DIR_PERM))?;
fs::set_permissions(&args.log_dir, Permissions::from_mode(LOG_DIR_PERM))?;
@@ -138,14 +148,29 @@ impl SyscareDaemon {
.start()
.context("Failed to initialize logger")?;
+ // Initialize config
+ debug!("Initializing configuation...");
+ let config_file = args.config_dir.join(CONFIG_FILE_NAME);
+ let config = match Config::parse(&config_file) {
+ Ok(config) => config,
+ Err(e) => {
+ warn!("{:?}", e);
+ info!("Using default configuration...");
+ let config = Config::default();
+ config.write(&config_file)?;
+
+ config
+ }
+ };
+
// Print panic to log incase it really happens
panic::set_hook(Box::new(|info| error!("{}", info)));
- Ok(Self { args })
+ Ok(Self { args, config })
}
}
-impl SyscareDaemon {
+impl Daemon {
fn daemonize(&self) -> Result<()> {
if !self.args.daemon {
return Ok(());
@@ -171,13 +196,24 @@ impl SyscareDaemon {
fn start_rpc_server(&self, io_handler: IoHandler) -> Result<Server> {
let socket_file = self.args.work_dir.join(SOCKET_FILE_NAME);
- let server = ServerBuilder::new(io_handler)
- .set_client_buffer_size(1)
- .start(
- socket_file
- .to_str()
- .context("Failed to convert socket path to string")?,
- )?;
+ let builder = ServerBuilder::new(io_handler).set_client_buffer_size(1);
+ let server = builder.start(
+ socket_file
+ .to_str()
+ .context("Failed to convert socket path to string")?,
+ )?;
+
+ let socket_owner = Uid::from_raw(self.config.daemon.socket.uid);
+ let socket_group = Gid::from_raw(self.config.daemon.socket.gid);
+ chown(&socket_file, Some(socket_owner), Some(socket_group))?;
+
+ fs::set_permissions(
+ &socket_file,
+ match socket_owner.as_raw() == socket_group.as_raw() {
+ true => Permissions::from_mode(SOCKET_FILE_PERM_STRICT),
+ false => Permissions::from_mode(SOCKET_FILE_PERM),
+ },
+ )?;
Ok(server)
}
@@ -227,7 +263,7 @@ impl SyscareDaemon {
}
fn main() {
- let daemon = match SyscareDaemon::new() {
+ let daemon = match Daemon::new() {
Ok(instance) => instance,
Err(e) => {
eprintln!("Error: {:?}", e);
diff --git a/upatchd/Cargo.toml b/upatchd/Cargo.toml
index dd9f5ca..fea0859 100644
--- a/upatchd/Cargo.toml
+++ b/upatchd/Cargo.toml
@@ -14,7 +14,7 @@ anyhow = { version = "1.0" }
clap = { version = "3.2", features = ["cargo", "derive"] }
daemonize = { version = "0.5" }
flexi_logger = { version = "0.24", features = ["compress"] }
-indexmap = { version = "1.9" }
+indexmap = { version = "1.9", features = ["serde"] }
jsonrpc-core = { version = "18.0" }
jsonrpc-derive = { version = "18.0" }
jsonrpc-ipc-server = { version = "18.0" }
diff --git a/upatchd/src/config.rs b/upatchd/src/config.rs
new file mode 100644
index 0000000..125770d
--- /dev/null
+++ b/upatchd/src/config.rs
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: Mulan PSL v2
+/*
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ * upatchd is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ *
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+use std::path::Path;
+
+use anyhow::{anyhow, Result};
+use serde::{Deserialize, Serialize};
+use syscare_common::fs;
+
+use crate::hijacker::HijackerConfig;
+
+const DEFAULT_SOCKET_UID: u32 = 0;
+const DEFAULT_SOCKET_GID: u32 = 0;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct SocketConfig {
+ pub uid: u32,
+ pub gid: u32,
+}
+
+impl Default for SocketConfig {
+ fn default() -> Self {
+ Self {
+ uid: DEFAULT_SOCKET_UID,
+ gid: DEFAULT_SOCKET_GID,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct DaemonConfig {
+ pub socket: SocketConfig,
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Config {
+ pub daemon: DaemonConfig,
+ pub hijacker: HijackerConfig,
+}
+
+impl Config {
+ pub fn parse<P: AsRef<Path>>(path: P) -> Result<Self> {
+ let config_path = path.as_ref();
+ let instance = serde_yaml::from_reader(fs::open_file(config_path)?)
+ .map_err(|_| anyhow!("Failed to parse config {}", config_path.display()))?;
+
+ Ok(instance)
+ }
+
+ pub fn write<P: AsRef<Path>>(&self, path: P) -> Result<()> {
+ let config_path = path.as_ref();
+ let config_file = fs::create_file(config_path)?;
+ serde_yaml::to_writer(config_file, self)
+ .map_err(|_| anyhow!("Failed to write config {}", config_path.display()))?;
+
+ Ok(())
+ }
+}
+
+#[test]
+fn test() -> Result<()> {
+ use anyhow::{ensure, Context};
+ use std::path::PathBuf;
+
+ let tmp_file = PathBuf::from("/tmp/upatchd.yaml");
+
+ let orig_cfg = Config::default();
+ println!("{:#?}", orig_cfg);
+
+ orig_cfg
+ .write(&tmp_file)
+ .context("Failed to write config")?;
+
+ let new_cfg = Config::parse(tmp_file).context("Failed to read config")?;
+ println!("{:#?}", new_cfg);
+
+ ensure!(orig_cfg == new_cfg, "Config does not match");
+
+ Ok(())
+}
diff --git a/upatchd/src/hijacker/config.rs b/upatchd/src/hijacker/config.rs
index f96cc05..5f97fb1 100644
--- a/upatchd/src/hijacker/config.rs
+++ b/upatchd/src/hijacker/config.rs
@@ -12,15 +12,10 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{
- collections::HashMap,
- ops::Deref,
- path::{Path, PathBuf},
-};
+use std::path::PathBuf;
-use anyhow::{anyhow, Result};
+use indexmap::{indexmap, IndexMap};
use serde::{Deserialize, Serialize};
-use syscare_common::fs;
const CC_BINARY: &str = "/usr/bin/cc";
const CXX_BINARY: &str = "/usr/bin/c++";
@@ -34,73 +29,21 @@ const GCC_HIJACKER: &str = "/usr/libexec/syscare/gcc-hijacker";
const GXX_HIJACKER: &str = "/usr/libexec/syscare/g++-hijacker";
const AS_HIJACKER: &str = "/usr/libexec/syscare/as-hijacker";
-#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
-pub struct HijackerConfig(HashMap<PathBuf, PathBuf>);
-
-impl HijackerConfig {
- pub fn parse_from<P: AsRef<Path>>(path: P) -> Result<Self> {
- let config_path = path.as_ref();
- let config_file = fs::open_file(config_path)?;
- let instance: Self = serde_yaml::from_reader(config_file)
- .map_err(|_| anyhow!("Failed to parse config {}", config_path.display()))?;
-
- Ok(instance)
- }
-
- pub fn write_to<P: AsRef<Path>>(&self, path: P) -> Result<()> {
- let config_path = path.as_ref();
- let config_file = fs::create_file(config_path)?;
- serde_yaml::to_writer(config_file, self)
- .map_err(|_| anyhow!("Failed to write config {}", config_path.display()))?;
-
- Ok(())
- }
-}
-
-impl Deref for HijackerConfig {
- type Target = HashMap<PathBuf, PathBuf>;
-
- fn deref(&self) -> &Self::Target {
- &self.0
- }
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct HijackerConfig {
+ pub mapping: IndexMap<PathBuf, PathBuf>,
}
impl Default for HijackerConfig {
fn default() -> Self {
- let mut map = HashMap::new();
- map.insert(PathBuf::from(CC_BINARY), PathBuf::from(CC_HIJACKER));
- map.insert(PathBuf::from(CXX_BINARY), PathBuf::from(CXX_HIJACKER));
- map.insert(PathBuf::from(GCC_BINARY), PathBuf::from(GCC_HIJACKER));
- map.insert(PathBuf::from(GXX_BINARY), PathBuf::from(GXX_HIJACKER));
- map.insert(PathBuf::from(AS_BINARY), PathBuf::from(AS_HIJACKER));
-
- Self(map)
+ Self {
+ mapping: indexmap! {
+ PathBuf::from(CC_BINARY) => PathBuf::from(CC_HIJACKER),
+ PathBuf::from(CXX_BINARY) => PathBuf::from(CXX_HIJACKER),
+ PathBuf::from(GCC_BINARY) => PathBuf::from(GCC_HIJACKER),
+ PathBuf::from(GXX_BINARY) => PathBuf::from(GXX_HIJACKER),
+ PathBuf::from(AS_BINARY) => PathBuf::from(AS_HIJACKER),
+ },
+ }
}
}
-
-impl std::fmt::Display for HijackerConfig {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_fmt(format_args!("{:#?}", &self.0))
- }
-}
-
-#[test]
-fn test() -> Result<()> {
- use anyhow::{ensure, Context};
-
- let tmp_file = PathBuf::from("/tmp/upatch_hijacker_config.yaml");
-
- let orig_cfg = HijackerConfig::default();
- println!("{}", orig_cfg);
-
- orig_cfg
- .write_to(&tmp_file)
- .context("Failed to write config")?;
-
- let new_cfg = HijackerConfig::parse_from(tmp_file).context("Failed to read config")?;
- println!("{}", new_cfg);
-
- ensure!(orig_cfg == new_cfg, "Config does not match");
-
- Ok(())
-}
diff --git a/upatchd/src/hijacker/mod.rs b/upatchd/src/hijacker/mod.rs
index 8ac12e7..d0f2c4d 100644
--- a/upatchd/src/hijacker/mod.rs
+++ b/upatchd/src/hijacker/mod.rs
@@ -12,7 +12,6 @@
* See the Mulan PSL v2 for more details.
*/
-use std::os::unix::prelude::MetadataExt;
use std::path::{Path, PathBuf};
use anyhow::{bail, Context, Result};
@@ -25,14 +24,14 @@ mod elf_resolver;
mod ioctl;
mod kmod;
-use config::HijackerConfig;
+pub use config::HijackerConfig;
use elf_resolver::ElfResolver;
use ioctl::HijackerIoctl;
use kmod::HijackerKmodGuard;
const KMOD_NAME: &str = "upatch_hijacker";
const KMOD_DEV_PATH: &str = "/dev/upatch-hijacker";
-const KMOD_FILE_PATH: &str = "/usr/libexec/syscare/upatch_hijacker.ko";
+const KMOD_PATH: &str = "/usr/libexec/syscare/upatch_hijacker.ko";
const HIJACK_SYMBOL_NAME: &str = "execve";
@@ -43,36 +42,6 @@ pub struct Hijacker {
}
impl Hijacker {
- fn initialize_config<P: AsRef<Path>>(config_path: P) -> Result<HijackerConfig> {
- const MODE_EXEC_MASK: u32 = 0o111;
-
- let config = match config_path.as_ref().exists() {
- true => HijackerConfig::parse_from(config_path)?,
- false => {
- info!("Generating default configuration...");
- let config = HijackerConfig::default();
- config.write_to(config_path)?;
-
- config
- }
- };
-
- for hijacker in config.values() {
- let is_executable_file = hijacker
- .symlink_metadata()
- .map(|m| m.is_file() && (m.mode() & MODE_EXEC_MASK != 0))
- .with_context(|| format!("Failed to read {} metadata", hijacker.display()))?;
- if !is_executable_file {
- bail!(
- "Hijack program {} is not an executable file",
- hijacker.display()
- );
- }
- }
-
- Ok(config)
- }
-
fn find_symbol_addr(symbol_name: &str) -> Result<(PathBuf, u64)> {
let exec_file = MappedFile::open(os::process::path())?;
let exec_resolver = ElfResolver::new(exec_file.as_bytes())?;
@@ -91,14 +60,9 @@ impl Hijacker {
}
impl Hijacker {
- pub fn new<P: AsRef<Path>>(config_path: P) -> Result<Self> {
- debug!("Initializing hijacker configuation...");
- let config = Self::initialize_config(config_path)
- .context("Failed to initialize hijacker configuration")?;
- info!("Using elf mapping: {}", config);
-
+ pub fn new(config: HijackerConfig) -> Result<Self> {
debug!("Initializing hijacker kernel module...");
- let kmod = HijackerKmodGuard::new(KMOD_NAME, KMOD_FILE_PATH)?;
+ let kmod = HijackerKmodGuard::new(KMOD_NAME, KMOD_PATH)?;
debug!("Initializing hijacker ioctl channel...");
let ioctl = HijackerIoctl::new(KMOD_DEV_PATH)?;
@@ -113,9 +77,9 @@ impl Hijacker {
ioctl.enable_hijacker(lib_path, offset)?;
Ok(Self {
+ config,
_kmod: kmod,
ioctl,
- config,
})
}
}
@@ -124,6 +88,7 @@ impl Hijacker {
fn get_hijacker<P: AsRef<Path>>(&self, exec_path: P) -> Result<&Path> {
let hijacker = self
.config
+ .mapping
.get(exec_path.as_ref())
.with_context(|| format!("Cannot find hijacker for {}", exec_path.as_ref().display()))?
.as_path();
diff --git a/upatchd/src/main.rs b/upatchd/src/main.rs
index 1007ebb..066e53e 100644
--- a/upatchd/src/main.rs
+++ b/upatchd/src/main.rs
@@ -22,16 +22,19 @@ use flexi_logger::{
};
use jsonrpc_core::IoHandler;
use jsonrpc_ipc_server::{Server, ServerBuilder};
-use log::{error, info, LevelFilter, Record};
+use log::{debug, error, info, warn, LevelFilter, Record};
+use nix::unistd::{chown, Gid, Uid};
use signal_hook::{consts::TERM_SIGNALS, iterator::Signals, low_level::signal_name};
use syscare_common::{fs, os};
mod args;
+mod config;
mod hijacker;
mod rpc;
use args::Arguments;
+use config::Config;
use rpc::{Skeleton, SkeletonImpl};
const DAEMON_NAME: &str = env!("CARGO_PKG_NAME");
@@ -46,17 +49,19 @@ const SOCKET_FILE_NAME: &str = "upatchd.sock";
const CONFIG_DIR_PERM: u32 = 0o700;
const WORK_DIR_PERM: u32 = 0o755;
const LOG_DIR_PERM: u32 = 0o700;
-const SOCKET_FILE_PERM: u32 = 0o666;
+const SOCKET_FILE_PERM: u32 = 0o660;
+const SOCKET_FILE_PERM_STRICT: u32 = 0o600;
const MAIN_THREAD_NAME: &str = "main";
const UNNAMED_THREAD_NAME: &str = "<unnamed>";
const LOG_FORMAT: &str = "%Y-%m-%d %H:%M:%S%.6f";
-struct UpatchDaemon {
+struct Daemon {
args: Arguments,
+ config: Config,
}
-impl UpatchDaemon {
+impl Daemon {
fn format_log(
w: &mut dyn std::io::Write,
now: &mut DeferredNow,
@@ -133,14 +138,28 @@ impl UpatchDaemon {
.start()
.context("Failed to initialize logger")?;
+ // Initialize config
+ debug!("Initializing configuation...");
+ let config_file = args.config_dir.join(CONFIG_FILE_NAME);
+ let config = match Config::parse(&config_file) {
+ Ok(config) => config,
+ Err(e) => {
+ warn!("{:?}", e);
+ info!("Using default configuration...");
+ let config = Config::default();
+ config.write(&config_file)?;
+
+ config
+ }
+ };
+
// Print panic to log incase it really happens
panic::set_hook(Box::new(|info| error!("{}", info)));
-
- Ok(Self { args })
+ Ok(Self { args, config })
}
}
-impl UpatchDaemon {
+impl Daemon {
fn daemonize(&self) -> Result<()> {
if !self.args.daemon {
return Ok(());
@@ -156,10 +175,11 @@ impl UpatchDaemon {
}
fn initialize_skeleton(&self) -> Result<IoHandler> {
- let mut io_handler = IoHandler::new();
+ let config = self.config.hijacker.clone();
+ let methods = SkeletonImpl::new(config)?.to_delegate();
- let config_file = self.args.config_dir.join(CONFIG_FILE_NAME);
- io_handler.extend_with(SkeletonImpl::new(config_file)?.to_delegate());
+ let mut io_handler = IoHandler::new();
+ io_handler.extend_with(methods);
Ok(io_handler)
}
@@ -173,7 +193,17 @@ impl UpatchDaemon {
.context("Failed to convert socket path to string")?,
)?;
- fs::set_permissions(&socket_file, Permissions::from_mode(SOCKET_FILE_PERM))?;
+ let socket_owner = Uid::from_raw(self.config.daemon.socket.uid);
+ let socket_group = Gid::from_raw(self.config.daemon.socket.gid);
+ chown(&socket_file, Some(socket_owner), Some(socket_group))?;
+
+ fs::set_permissions(
+ &socket_file,
+ match socket_owner.as_raw() == socket_group.as_raw() {
+ true => Permissions::from_mode(SOCKET_FILE_PERM_STRICT),
+ false => Permissions::from_mode(SOCKET_FILE_PERM),
+ },
+ )?;
Ok(server)
}
@@ -183,6 +213,7 @@ impl UpatchDaemon {
info!("Upatch Daemon - {}", DAEMON_VERSION);
info!("================================");
info!("Start with {:#?}", self.args);
+ info!("Using {:#?}", self.config);
self.daemonize()?;
info!("Initializing skeleton...");
@@ -213,7 +244,7 @@ impl UpatchDaemon {
}
fn main() {
- let daemon = match UpatchDaemon::new() {
+ let daemon = match Daemon::new() {
Ok(instance) => instance,
Err(e) => {
eprintln!("Error: {:?}", e);
diff --git a/upatchd/src/rpc/skeleton_impl.rs b/upatchd/src/rpc/skeleton_impl.rs
index a334120..d725166 100644
--- a/upatchd/src/rpc/skeleton_impl.rs
+++ b/upatchd/src/rpc/skeleton_impl.rs
@@ -12,12 +12,12 @@
* See the Mulan PSL v2 for more details.
*/
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
use anyhow::{Context, Result};
use log::{debug, info};
-use crate::hijacker::Hijacker;
+use crate::hijacker::{Hijacker, HijackerConfig};
use super::{
function::{RpcFunction, RpcResult},
@@ -29,10 +29,10 @@ pub struct SkeletonImpl {
}
impl SkeletonImpl {
- pub fn new<P: AsRef<Path>>(config_path: P) -> Result<Self> {
+ pub fn new(config: HijackerConfig) -> Result<Self> {
debug!("Initializing hijacker...");
Ok(Self {
- hijacker: Hijacker::new(config_path).context("Failed to initialize hijacker")?,
+ hijacker: Hijacker::new(config).context("Failed to initialize hijacker")?,
})
}
}
--
2.34.1

View File

@ -1,132 +0,0 @@
From b9ae8a1ea14d46b3f4ba887fb10f9898c6f5cc53 Mon Sep 17 00:00:00 2001
From: ningyu <ningyu9@huawei.com>
Date: Sat, 11 May 2024 08:06:58 +0000
Subject: [PATCH] upatch-manage: Fixed the core dump issue after applying hot
patches to nginx on x86_64 architecture.
For non-dynamic library elf, do not place the global variables in the GOT table
---
upatch-manage/arch/x86_64/resolve.c | 16 ++++++++++++---
upatch-manage/upatch-elf.c | 32 +++++++++++++++++++++++++++--
upatch-manage/upatch-elf.h | 5 ++++-
3 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/upatch-manage/arch/x86_64/resolve.c b/upatch-manage/arch/x86_64/resolve.c
index 45261dd..5432b20 100644
--- a/upatch-manage/arch/x86_64/resolve.c
+++ b/upatch-manage/arch/x86_64/resolve.c
@@ -123,10 +123,20 @@ unsigned long insert_got_table(struct upatch_elf *uelf, struct object_file *obj,
goto out;
}
- elf_addr = setup_got_table(uelf, jmp_addr, tls_addr);
+ if (uelf->relf->info.is_dyn && !uelf->relf->info.is_pie) {
+ elf_addr = setup_got_table(uelf, jmp_addr, tls_addr);
+
+ log_debug("0x%lx: jmp_addr=0x%lx\n", elf_addr, jmp_addr);
+
+ } else {
+ /*
+ * For non-dynamic library files, global variables are not placed in the GOT table
+ */
+ elf_addr = jmp_addr;
+ log_debug("For non-dynamic library: jmp_addr=0x%lx\n", jmp_addr);
+ }
- log_debug("0x%lx: jmp_addr=0x%lx\n", elf_addr, jmp_addr);
out:
return elf_addr;
-}
\ No newline at end of file
+}
diff --git a/upatch-manage/upatch-elf.c b/upatch-manage/upatch-elf.c
index 02444eb..78c7fd7 100644
--- a/upatch-manage/upatch-elf.c
+++ b/upatch-manage/upatch-elf.c
@@ -132,6 +132,31 @@ int upatch_init(struct upatch_elf *uelf, const char *name)
return 0;
}
+static bool is_pie_elf(struct running_elf *relf)
+{
+ GElf_Shdr *shdr = &relf->info.shdrs[relf->index.dynamic];
+ GElf_Dyn *dyns = (void *)relf->info.hdr + shdr->sh_offset;
+ if (relf->index.dynamic == 0) {
+ return false;
+ }
+ for (Elf64_Xword i = 0; i < shdr->sh_size / sizeof(GElf_Dyn); i++) {
+ log_debug("Syminfo %lx, %lx\n", dyns[i].d_tag, dyns[i].d_un.d_val);
+ if (dyns[i].d_tag == DT_FLAGS_1) {
+ if ((dyns[i].d_un.d_val & DF_1_PIE) != 0)
+ return true;
+ break;
+ }
+ }
+ return false;
+}
+
+static bool is_dyn_elf(struct running_elf *relf)
+{
+ GElf_Ehdr *ehdr = relf->info.hdr;
+
+ return ehdr->e_type == ET_DYN;
+}
+
int binary_init(struct running_elf *relf, const char *name)
{
int ret = open_elf(&relf->info, name);
@@ -156,7 +181,8 @@ int binary_init(struct running_elf *relf, const char *name)
relf->dynstrtab = (char *)relf->info.hdr +
relf->info.shdrs[relf->info.shdrs[i].sh_link].sh_offset;
} else if (relf->info.shdrs[i].sh_type == SHT_DYNAMIC) {
- /* Currently, we don't utilize it */
+ log_debug("Found section '%s', idx=%d\n", DYNAMIC_NAME, i);
+ relf->index.dynamic = i;
} else if (streql(sec_name, PLT_RELA_NAME) &&
relf->info.shdrs[i].sh_type == SHT_RELA) {
log_debug("Found section '%s', idx=%d\n", PLT_RELA_NAME, i);
@@ -177,7 +203,9 @@ int binary_init(struct running_elf *relf, const char *name)
break;
}
}
-
+
+ relf->info.is_pie = is_pie_elf(relf);
+ relf->info.is_dyn = is_dyn_elf(relf);
return 0;
}
diff --git a/upatch-manage/upatch-elf.h b/upatch-manage/upatch-elf.h
index fe68b7e..481fec9 100644
--- a/upatch-manage/upatch-elf.h
+++ b/upatch-manage/upatch-elf.h
@@ -30,6 +30,7 @@
#define SYMTAB_NAME ".symtab"
#define DYNSYM_NAME ".dynsym"
+#define DYNAMIC_NAME ".dynamic"
#define GOT_RELA_NAME ".rela.dyn"
#define PLT_RELA_NAME ".rela.plt"
#define BUILD_ID_NAME ".note.gnu.build-id"
@@ -95,6 +96,8 @@ struct elf_info {
char *shstrtab;
unsigned int num_build_id;
+ bool is_pie;
+ bool is_dyn;
};
struct running_elf {
@@ -111,7 +114,7 @@ struct running_elf {
struct {
unsigned int sym, str;
unsigned int rela_dyn, rela_plt;
- unsigned int dynsym, dynstr;
+ unsigned int dynsym, dynstr, dynamic;
} index;
/* load bias, used to handle ASLR */
--
2.34.1

View File

@ -1,144 +0,0 @@
From fac8aa17d540e54fa0443015089cdc72c5da72e3 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Sat, 11 May 2024 17:31:46 +0800
Subject: [PATCH] upatch-diff: fix 'lookup_relf failed' issue
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-diff/elf-create.c | 24 ++++++++++-------
upatch-diff/running-elf.c | 57 +++++++++++++--------------------------
2 files changed, 32 insertions(+), 49 deletions(-)
diff --git a/upatch-diff/elf-create.c b/upatch-diff/elf-create.c
index de4cb57..873b3a9 100644
--- a/upatch-diff/elf-create.c
+++ b/upatch-diff/elf-create.c
@@ -135,8 +135,9 @@ void upatch_create_patches_sections(struct upatch_elf *uelf, struct running_elf
/* find changed func */
list_for_each_entry(sym, &uelf->symbols, list) {
- if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent)
+ if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent) {
continue;
+ }
nr++;
}
@@ -146,24 +147,27 @@ void upatch_create_patches_sections(struct upatch_elf *uelf, struct running_elf
funcs = sec->data->d_buf;
strsym = find_symbol_by_name(&uelf->symbols, ".upatch.strings");
- if (!strsym)
- ERROR("can't find .upatch.strings symbol.");
+ if (!strsym) {
+ ERROR("Cannot find symbol '.upatch.strings'");
+ }
list_for_each_entry(sym, &uelf->symbols, list) {
- if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent)
+ if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent) {
continue;
+ }
- if (!lookup_relf(relf, sym, &symbol))
- ERROR("lookup_relf failed.");
+ if (!lookup_relf(relf, sym, &symbol)) {
+ ERROR("Cannot find symbol '%s' in %s", sym->name, g_relf_name);
+ }
- if (sym->bind == STB_LOCAL && symbol.global)
- ERROR("can't find local symbol '%s' in symbol table.", sym->name);
+ if (sym->bind == STB_LOCAL && symbol.global) {
+ ERROR("Cannot find local symbol '%s' in symbol table.", sym->name);
+ }
- log_debug("lookup for %s: symbol name %s sympos=%lu size=%lu .\n",
+ log_debug("lookup for %s: symbol name %s sympos=%lu size=%lu.\n",
sym->name, symbol.symbol->name, symbol.sympos, symbol.symbol->size);
/* ATTENTION: kpatch convert global symbols to local symbols here. */
-
funcs[index].old_addr = symbol.symbol->addr;
funcs[index].old_size = symbol.symbol->size;
funcs[index].new_size = sym->sym.st_size;
diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c
index 037f5fc..3bb35e7 100644
--- a/upatch-diff/running-elf.c
+++ b/upatch-diff/running-elf.c
@@ -113,55 +113,34 @@ int relf_destroy(struct running_elf *relf)
return 0;
}
-bool lookup_relf(struct running_elf *relf, struct symbol *lookup_sym,
- struct lookup_result *result)
+bool lookup_relf(struct running_elf *relf,
+ struct symbol *lookup_sym, struct lookup_result *result)
{
- int i;
- struct debug_symbol *sym;
+ struct debug_symbol *symbol = NULL;
unsigned long sympos = 0;
- bool in_file = false;
+ log_debug("looking up symbol '%s'\n", lookup_sym->name);
memset(result, 0, sizeof(*result));
- for (i = 0; i < relf->obj_nr; i ++) {
- sym = &relf->obj_syms[i];
- if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name))
- sympos ++;
+ for (int i = 0; i < relf->obj_nr; i++) {
+ symbol = &relf->obj_syms[i];
+ sympos++;
- if (lookup_sym->relf_sym == sym) {
- in_file = true;
+ if (strcmp(symbol->name, lookup_sym->name) != 0) {
continue;
}
-
- if (!in_file)
- continue;
-
- if (sym->type == STT_FILE)
- break;
-
- if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name)) {
- if (result->symbol)
- ERROR("duplicate local symbol found for %s", lookup_sym->name);
-
- result->symbol = sym;
- result->sympos = sympos;
- result->global = false;
+ if ((result->symbol != NULL) &&
+ (result->symbol->bind == symbol->bind)) {
+ ERROR("Found duplicate symbol '%s' in %s",
+ lookup_sym->name, g_relf_name);
}
- }
-
- if (!!result->symbol)
- return !!result->symbol;
- for (i = 0; i < relf->obj_nr; i ++) {
- sym = &relf->obj_syms[i];
- if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
- !strcmp(sym->name, lookup_sym->name)) {
- if (result->symbol)
- ERROR("duplicated global symbol for %s \n", lookup_sym->name);
- result->symbol = sym;
- result->global = true;
- }
+ result->symbol = symbol;
+ result->sympos = sympos;
+ result->global =
+ ((symbol->bind == STB_GLOBAL) || (symbol->bind == STB_WEAK));
+ log_normal("found symbol '%s'\n", lookup_sym->name);
}
- return !!result->symbol;
+ return (result->symbol != NULL);
}
--
2.34.1

View File

@ -1,165 +0,0 @@
From 2d711186e1c134b069102e72d6d451942c931eb5 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Mon, 13 May 2024 21:27:13 +0800
Subject: [PATCH] upatch-diff: only check changed file symbols
1. sync compare results (SAME/NEW/CHANGED) to correlated objects
2. mark file changes by looking up symbol changes
3. check orignal object & debuginfo when file changes were detected
4. defer symbol check until after calculation changes
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-diff/create-diff-object.c | 26 +++++++++++++--
upatch-diff/elf-compare.c | 57 ++++++++++++++++++--------------
upatch-diff/running-elf.c | 2 +-
3 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/upatch-diff/create-diff-object.c b/upatch-diff/create-diff-object.c
index 01c58b8..1a05869 100644
--- a/upatch-diff/create-diff-object.c
+++ b/upatch-diff/create-diff-object.c
@@ -481,12 +481,32 @@ static void find_debug_symbol(struct upatch_elf *uelf, struct running_elf *relf)
struct symbol *file_sym = NULL;
list_for_each_entry(file_sym, &uelf->symbols, list) {
- if (file_sym->type == STT_FILE) {
+ if ((file_sym->type == STT_FILE) && (file_sym->status == CHANGED)) {
+ log_debug("file '%s' is CHANGED\n", file_sym->name);
find_local_syms(uelf, relf, file_sym);
}
}
}
+static void mark_file_symbols(struct upatch_elf *uelf)
+{
+ struct symbol *curr_sym = NULL;
+ struct symbol *file_sym = NULL;
+
+ list_for_each_entry(curr_sym, &uelf->symbols, list) {
+ if (curr_sym->type == STT_FILE) {
+ file_sym = curr_sym;
+ continue;
+ }
+ if ((file_sym == NULL) || (file_sym->status == CHANGED)) {
+ continue;
+ }
+ if (curr_sym->status == CHANGED) {
+ file_sym->status = CHANGED;
+ }
+ }
+}
+
static void mark_grouped_sections(struct upatch_elf *uelf)
{
struct section *groupsec, *sec;
@@ -937,8 +957,6 @@ int main(int argc, char*argv[])
detect_child_functions(&uelf_source);
detect_child_functions(&uelf_patched);
- find_debug_symbol(&uelf_source, &relf);
-
mark_grouped_sections(&uelf_patched);
replace_section_syms(&uelf_source);
@@ -952,6 +970,8 @@ int main(int argc, char*argv[])
mark_ignored_sections(&uelf_patched);
upatch_compare_correlated_elements(&uelf_patched);
+ mark_file_symbols(&uelf_source);
+ find_debug_symbol(&uelf_source, &relf);
mark_ignored_functions_same(&uelf_patched);
mark_ignored_sections_same(&uelf_patched);
diff --git a/upatch-diff/elf-compare.c b/upatch-diff/elf-compare.c
index 9b857b1..ef8dd23 100644
--- a/upatch-diff/elf-compare.c
+++ b/upatch-diff/elf-compare.c
@@ -336,38 +336,45 @@ static bool line_macro_change_only(struct upatch_elf *uelf, struct section *sec)
return false;
}
+static inline void update_section_status(struct section *sec, enum status status)
+{
+ if (sec == NULL) {
+ return;
+ }
+ if (sec->twin != NULL) {
+ sec->twin->status = status;
+ }
+ if (is_rela_section(sec)) {
+ if ((sec->base != NULL) &&
+ (sec->base->sym != NULL)) {
+ sec->base->sym->status = status;
+ }
+ }
+ else {
+ if (sec->sym != NULL) {
+ sec->sym->status = status;
+ }
+ }
+}
+
void upatch_compare_sections(struct upatch_elf *uelf)
{
- struct section *sec;
- struct list_head *seclist = &uelf->sections;
+ struct section *sec = NULL;
- /* compare all sections */
- list_for_each_entry(sec, seclist, list) {
- if (sec->twin)
- compare_correlated_section(sec, sec->twin);
- else
+ list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->twin == NULL) {
sec->status = NEW;
- }
-
- /* exclude WARN-only, might_sleep changes */
- list_for_each_entry(sec, seclist, list) {
+ }
+ else {
+ compare_correlated_section(sec, sec->twin);
+ }
+ /* exclude WARN-only, might_sleep changes */
if (line_macro_change_only(uelf, sec)) {
log_debug("reverting macro / line number section %s status to SAME\n", sec->name);
sec->status = SAME;
}
- }
-
- /* sync symbol status */
- list_for_each_entry(sec, seclist, list) {
- if (is_rela_section(sec)) {
- /* sync bundleable symbol for relocation section */
- if (sec->base->sym && sec->base->sym->status != CHANGED)
- sec->base->sym->status = sec->status;
- } else {
- struct symbol *sym = sec->sym;
- if (sym && sym->status != CHANGED)
- sym->status = sec->status;
- /* TODO: handle child func */
- }
+ /* sync status */
+ update_section_status(sec, sec->status);
+ update_section_status(sec->twin, sec->status);
}
}
\ No newline at end of file
diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c
index 3bb35e7..676880f 100644
--- a/upatch-diff/running-elf.c
+++ b/upatch-diff/running-elf.c
@@ -139,7 +139,7 @@ bool lookup_relf(struct running_elf *relf,
result->sympos = sympos;
result->global =
((symbol->bind == STB_GLOBAL) || (symbol->bind == STB_WEAK));
- log_normal("found symbol '%s'\n", lookup_sym->name);
+ log_debug("found symbol '%s'\n", lookup_sym->name);
}
return (result->symbol != NULL);
--
2.34.1

View File

@ -1,27 +0,0 @@
From 06ef9f212e17cdaa93dc5255d2c881c0b52d603f Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 14 May 2024 14:10:05 +0800
Subject: [PATCH] upatch-diff: remove rela check while build rebuilding
.eh_frame
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch-diff/elf-debug.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/upatch-diff/elf-debug.c b/upatch-diff/elf-debug.c
index 6b5fc53..f9c5327 100644
--- a/upatch-diff/elf-debug.c
+++ b/upatch-diff/elf-debug.c
@@ -181,8 +181,6 @@ void upatch_rebuild_eh_frame(struct section *sec)
if (found_rela)
break;
}
- if (!found_rela)
- ERROR("No FDE found for relocation at 0x%x \n", offset);
}
/*
--
2.34.1

View File

@ -1,27 +0,0 @@
From cf5217d55b2a603cfa0a852d876809c536835f18 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 17 May 2024 14:46:30 +0800
Subject: [PATCH] syscared: fix 'apply kernel module patch failure' issue
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/patch/driver/kpatch/mod.rs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/syscared/src/patch/driver/kpatch/mod.rs b/syscared/src/patch/driver/kpatch/mod.rs
index 307efb5..970da92 100644
--- a/syscared/src/patch/driver/kpatch/mod.rs
+++ b/syscared/src/patch/driver/kpatch/mod.rs
@@ -128,6 +128,9 @@ impl KernelPatchDriver {
debug!("Patch target: '{}'", patch_target);
debug!("Current kernel: '{}'", current_kernel.to_string_lossy());
+ if !patch_target.starts_with("KERNEL_NAME_PREFIX") {
+ return Ok(());
+ }
ensure!(
current_kernel == patch_target,
"Kpatch: Patch is incompatible",
--
2.34.1

View File

@ -1,40 +0,0 @@
From bf34a1c52841e9b33a6239405b7e15b42ddfe8b3 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Thu, 23 May 2024 09:18:08 +0800
Subject: [PATCH] syscare-build: fix 'build oot module failure' issue
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-build/src/package/rpm/pkg_builder.rs | 1 +
syscare-build/src/patch/kernel_patch/kpatch_builder.rs | 3 +++
2 files changed, 4 insertions(+)
diff --git a/syscare-build/src/package/rpm/pkg_builder.rs b/syscare-build/src/package/rpm/pkg_builder.rs
index 5d7ae54..37f4444 100644
--- a/syscare-build/src/package/rpm/pkg_builder.rs
+++ b/syscare-build/src/package/rpm/pkg_builder.rs
@@ -97,6 +97,7 @@ impl PackageBuilder for RpmPackageBuilder<'_> {
.arg("--define")
.arg("__spec_install_post %{__arch_install_post}")
.arg("--nocheck")
+ .arg("--noclean")
.arg("-bb")
.arg(spec_file)
.run()?
diff --git a/syscare-build/src/patch/kernel_patch/kpatch_builder.rs b/syscare-build/src/patch/kernel_patch/kpatch_builder.rs
index ba49661..bcae962 100644
--- a/syscare-build/src/patch/kernel_patch/kpatch_builder.rs
+++ b/syscare-build/src/patch/kernel_patch/kpatch_builder.rs
@@ -227,6 +227,9 @@ impl KernelPatchBuilder {
if let Some(oot_module) = &kbuild_entity.module_path {
cmd_args.arg("--oot-module").arg(oot_module);
+ cmd_args
+ .arg("--oot-module-src")
+ .arg(&kbuild_entity.source_dir);
}
cmd_args.args(kbuild_params.patch_files.iter().map(|patch| &patch.path));
--
2.34.1

View File

@ -1,241 +0,0 @@
From 42d7bdb932dfb5bb511ab2698c4fe4f3fc4be0be Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 29 May 2024 22:06:09 +0800
Subject: [PATCH] all: finding executable from environment variables
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-build/src/main.rs | 10 ++++++++--
syscare-build/src/patch/user_patch/upatch_builder.rs | 2 +-
syscare/src/executor/build.rs | 7 +++----
syscare/src/main.rs | 10 ++++++++--
syscared/src/main.rs | 10 ++++++++--
syscared/src/patch/driver/upatch/sys.rs | 2 +-
upatch-build/src/main.rs | 9 ++++++++-
7 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/syscare-build/src/main.rs b/syscare-build/src/main.rs
index 8928218..1faa803 100644
--- a/syscare-build/src/main.rs
+++ b/syscare-build/src/main.rs
@@ -12,7 +12,7 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{process, sync::Arc};
+use std::{env, process, sync::Arc};
use anyhow::{bail, ensure, Context, Result};
use flexi_logger::{
@@ -22,7 +22,7 @@ use lazy_static::lazy_static;
use log::{error, info, LevelFilter, Record};
use syscare_abi::{PackageInfo, PackageType, PatchInfo, PatchType};
-use syscare_common::{fs, os};
+use syscare_common::{concat_os, fs, os};
mod args;
mod build_params;
@@ -44,6 +44,9 @@ const CLI_VERSION: &str = env!("CARGO_PKG_VERSION");
const CLI_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const CLI_UMASK: u32 = 0o022;
+const PATH_ENV_NAME: &str = "PATH";
+const PATH_ENV_VALUE: &str = "/usr/libexec/syscare";
+
const LOG_FILE_NAME: &str = "build";
const KERNEL_PKG_NAME: &str = "kernel";
@@ -70,6 +73,9 @@ impl SyscareBuild {
fn new() -> Result<Self> {
// Initialize arguments & prepare environments
os::umask::set_umask(CLI_UMASK);
+ if let Some(path_env) = env::var_os(PATH_ENV_NAME) {
+ env::set_var(PATH_ENV_NAME, concat_os!(PATH_ENV_VALUE, ":", path_env));
+ }
let args = Arguments::new()?;
let build_root = BuildRoot::new(&args.build_root)?;
diff --git a/syscare-build/src/patch/user_patch/upatch_builder.rs b/syscare-build/src/patch/user_patch/upatch_builder.rs
index 1e0e6b6..255c2d3 100644
--- a/syscare-build/src/patch/user_patch/upatch_builder.rs
+++ b/syscare-build/src/patch/user_patch/upatch_builder.rs
@@ -34,7 +34,7 @@ use crate::{build_params::BuildParameters, package::PackageImpl, patch::PatchBui
use super::{elf_relation::ElfRelation, DEBUGINFO_FILE_EXT};
-const UPATCH_BUILD_BIN: &str = "/usr/libexec/syscare/upatch-build";
+const UPATCH_BUILD_BIN: &str = "upatch-build";
const RPMBUILD_BIN: &str = "rpmbuild";
struct UBuildParameters {
diff --git a/syscare/src/executor/build.rs b/syscare/src/executor/build.rs
index f9027c7..6d3866f 100644
--- a/syscare/src/executor/build.rs
+++ b/syscare/src/executor/build.rs
@@ -19,22 +19,21 @@ use anyhow::{bail, Context, Result};
use super::CommandExecutor;
use crate::args::SubCommand;
-const SYSCARE_BUILD_PATH: &str = "/usr/libexec/syscare/syscare-build";
+const SYSCARE_BUILD_BIN: &str = "syscare-build";
pub struct BuildCommandExecutor;
impl CommandExecutor for BuildCommandExecutor {
fn invoke(&self, command: &SubCommand) -> Result<Option<i32>> {
if let SubCommand::Build { args } = command {
- let e = Command::new(SYSCARE_BUILD_PATH).args(args).exec();
+ let e = Command::new(SYSCARE_BUILD_BIN).args(args).exec();
match e.kind() {
std::io::ErrorKind::NotFound => {
bail!("Package syscare-build is not installed");
}
_ => {
- return Err(e)
- .with_context(|| format!("Failed to start {}", SYSCARE_BUILD_PATH))
+ return Err(e).with_context(|| format!("Failed to start {}", SYSCARE_BUILD_BIN))
}
}
}
diff --git a/syscare/src/main.rs b/syscare/src/main.rs
index c709f6a..dea5717 100644
--- a/syscare/src/main.rs
+++ b/syscare/src/main.rs
@@ -12,7 +12,7 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{process, rc::Rc};
+use std::{env, process, rc::Rc};
use anyhow::{Context, Result};
use flexi_logger::{DeferredNow, LogSpecification, Logger, LoggerHandle, WriteMode};
@@ -25,13 +25,16 @@ mod rpc;
use args::Arguments;
use executor::{build::BuildCommandExecutor, patch::PatchCommandExecutor, CommandExecutor};
use rpc::{RpcProxy, RpcRemote};
-use syscare_common::os;
+use syscare_common::{concat_os, os};
pub const CLI_NAME: &str = env!("CARGO_PKG_NAME");
pub const CLI_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const CLI_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const CLI_UMASK: u32 = 0o077;
+const PATH_ENV_NAME: &str = "PATH";
+const PATH_ENV_VALUE: &str = "/usr/libexec/syscare";
+
const SOCKET_FILE_NAME: &str = "syscared.sock";
const PATCH_OP_LOCK_NAME: &str = "patch_op.lock";
@@ -52,6 +55,9 @@ impl SyscareCLI {
fn new() -> Result<Self> {
// Initialize arguments & prepare environments
os::umask::set_umask(CLI_UMASK);
+ if let Some(path_env) = env::var_os(PATH_ENV_NAME) {
+ env::set_var(PATH_ENV_NAME, concat_os!(PATH_ENV_VALUE, ":", path_env));
+ }
let args = Arguments::new()?;
diff --git a/syscared/src/main.rs b/syscared/src/main.rs
index b840abf..5c60ecf 100644
--- a/syscared/src/main.rs
+++ b/syscared/src/main.rs
@@ -12,7 +12,7 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{fs::Permissions, os::unix::fs::PermissionsExt, panic, process, sync::Arc};
+use std::{env, fs::Permissions, os::unix::fs::PermissionsExt, panic, process, sync::Arc};
use anyhow::{ensure, Context, Result};
use daemonize::Daemonize;
@@ -28,7 +28,7 @@ use parking_lot::RwLock;
use patch::manager::PatchManager;
use signal_hook::{consts::TERM_SIGNALS, iterator::Signals, low_level::signal_name};
-use syscare_common::{fs, os};
+use syscare_common::{concat_os, fs, os};
mod args;
mod config;
@@ -49,6 +49,9 @@ const DAEMON_VERSION: &str = env!("CARGO_PKG_VERSION");
const DAEMON_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const DAEMON_UMASK: u32 = 0o077;
+const PATH_ENV_NAME: &str = "PATH";
+const PATH_ENV_VALUE: &str = "/usr/libexec/syscare";
+
const CONFIG_FILE_NAME: &str = "syscared.yaml";
const PID_FILE_NAME: &str = "syscared.pid";
const SOCKET_FILE_NAME: &str = "syscared.sock";
@@ -107,6 +110,9 @@ impl Daemon {
// Initialize arguments & prepare environments
os::umask::set_umask(DAEMON_UMASK);
+ if let Some(path_env) = env::var_os(PATH_ENV_NAME) {
+ env::set_var(PATH_ENV_NAME, concat_os!(PATH_ENV_VALUE, ":", path_env));
+ }
let args = Arguments::new()?;
fs::create_dir_all(&args.config_dir)?;
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
index a388bc6..1990289 100644
--- a/syscared/src/patch/driver/upatch/sys.rs
+++ b/syscared/src/patch/driver/upatch/sys.rs
@@ -6,7 +6,7 @@ use uuid::Uuid;
use syscare_common::process::Command;
-const UPATCH_MANAGE_BIN: &str = "/usr/libexec/syscare/upatch-manage";
+const UPATCH_MANAGE_BIN: &str = "upatch-manage";
pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path) -> Result<()> {
let exit_code = Command::new(UPATCH_MANAGE_BIN)
diff --git a/upatch-build/src/main.rs b/upatch-build/src/main.rs
index b5c14a8..473b0a7 100644
--- a/upatch-build/src/main.rs
+++ b/upatch-build/src/main.rs
@@ -13,6 +13,7 @@
*/
use std::{
+ env,
ffi::OsStr,
fs::Permissions,
os::unix::fs::PermissionsExt,
@@ -54,6 +55,9 @@ const CLI_VERSION: &str = env!("CARGO_PKG_VERSION");
const CLI_ABOUT: &str = env!("CARGO_PKG_DESCRIPTION");
const CLI_UMASK: u32 = 0o022;
+const PATH_ENV_NAME: &str = "PATH";
+const PATH_ENV_VALUE: &str = "/usr/libexec/syscare";
+
const LOG_FILE_NAME: &str = "build";
struct BuildInfo {
@@ -83,6 +87,9 @@ impl UpatchBuild {
fn new() -> Result<Self> {
// Initialize arguments & prepare environments
os::umask::set_umask(CLI_UMASK);
+ if let Some(path_env) = env::var_os(PATH_ENV_NAME) {
+ env::set_var(PATH_ENV_NAME, concat_os!(PATH_ENV_VALUE, ":", path_env));
+ }
let args = Arguments::new()?;
let build_root = BuildRoot::new(&args.build_root)?;
@@ -196,7 +203,7 @@ impl UpatchBuild {
output_dir: &Path,
verbose: bool,
) -> Result<()> {
- const UPATCH_DIFF_BIN: &str = "/usr/libexec/syscare/upatch-diff";
+ const UPATCH_DIFF_BIN: &str = "upatch-diff";
let ouput_name = original_object.file_name().with_context(|| {
format!(
--
2.34.1

View File

@ -1,901 +0,0 @@
From abdafc1728b233b93c42b76034e19286e3fcbda7 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 21 May 2024 15:01:48 +0800
Subject: [PATCH] all: remove redundant code
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-build/src/build_root/mod.rs | 20 +-
syscare-build/src/build_root/package_root.rs | 6 -
syscare-build/src/build_root/patch_root.rs | 6 -
syscare-build/src/package/dependency.rs | 10 -
syscare-build/src/package/mod.rs | 1 -
syscare-build/src/package/rpm/mod.rs | 4 -
syscare-common/src/os/disk.rs | 64 ----
syscare-common/src/os/grub.rs | 312 ------------------
syscare-common/src/os/kernel.rs | 43 +--
syscare-common/src/os/mod.rs | 2 -
syscare-common/src/util/digest.rs | 7 -
syscared/src/fast_reboot/manager.rs | 123 -------
syscared/src/fast_reboot/mod.rs | 17 -
syscared/src/main.rs | 7 +-
syscared/src/rpc/skeleton/fast_reboot.rs | 21 --
syscared/src/rpc/skeleton/mod.rs | 2 -
syscared/src/rpc/skeleton_impl/fast_reboot.rs | 42 ---
syscared/src/rpc/skeleton_impl/mod.rs | 2 -
18 files changed, 3 insertions(+), 686 deletions(-)
delete mode 100644 syscare-build/src/package/dependency.rs
delete mode 100644 syscare-common/src/os/disk.rs
delete mode 100644 syscare-common/src/os/grub.rs
delete mode 100644 syscared/src/fast_reboot/manager.rs
delete mode 100644 syscared/src/fast_reboot/mod.rs
delete mode 100644 syscared/src/rpc/skeleton/fast_reboot.rs
delete mode 100644 syscared/src/rpc/skeleton_impl/fast_reboot.rs
diff --git a/syscare-build/src/build_root/mod.rs b/syscare-build/src/build_root/mod.rs
index 81de6b2..6a12788 100644
--- a/syscare-build/src/build_root/mod.rs
+++ b/syscare-build/src/build_root/mod.rs
@@ -12,11 +12,7 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{
- ffi::OsStr,
- ops::Deref,
- path::{Path, PathBuf},
-};
+use std::path::{Path, PathBuf};
use anyhow::Result;
use syscare_common::fs;
@@ -61,17 +57,3 @@ impl BuildRoot {
Ok(())
}
}
-
-impl Deref for BuildRoot {
- type Target = Path;
-
- fn deref(&self) -> &Self::Target {
- &self.path
- }
-}
-
-impl AsRef<OsStr> for BuildRoot {
- fn as_ref(&self) -> &OsStr {
- self.as_os_str()
- }
-}
diff --git a/syscare-build/src/build_root/package_root.rs b/syscare-build/src/build_root/package_root.rs
index abb7a86..724a42b 100644
--- a/syscare-build/src/build_root/package_root.rs
+++ b/syscare-build/src/build_root/package_root.rs
@@ -50,9 +50,3 @@ impl PackageRoot {
})
}
}
-
-impl AsRef<Path> for PackageRoot {
- fn as_ref(&self) -> &Path {
- &self.path
- }
-}
diff --git a/syscare-build/src/build_root/patch_root.rs b/syscare-build/src/build_root/patch_root.rs
index b780e32..af8ec6b 100644
--- a/syscare-build/src/build_root/patch_root.rs
+++ b/syscare-build/src/build_root/patch_root.rs
@@ -44,9 +44,3 @@ impl PatchRoot {
})
}
}
-
-impl AsRef<Path> for PatchRoot {
- fn as_ref(&self) -> &Path {
- &self.path
- }
-}
diff --git a/syscare-build/src/package/dependency.rs b/syscare-build/src/package/dependency.rs
deleted file mode 100644
index 37bdf92..0000000
--- a/syscare-build/src/package/dependency.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-pub struct PackageDependency {
- requires: HashSet<String>,
- conflicts: HashSet<String>,
- suggests: HashSet<String>,
- recommends: HashSet<String>,
-}
-
-impl PackageDependency {
-
-}
\ No newline at end of file
diff --git a/syscare-build/src/package/mod.rs b/syscare-build/src/package/mod.rs
index 9ba29a1..72b555a 100644
--- a/syscare-build/src/package/mod.rs
+++ b/syscare-build/src/package/mod.rs
@@ -33,7 +33,6 @@ pub use spec_writer::*;
pub use tar::*;
trait Package {
- fn extension(&self) -> &'static str;
fn parse_package_info(&self, pkg_path: &Path) -> Result<PackageInfo>;
fn query_package_files(&self, pkg_path: &Path) -> Result<Vec<PathBuf>>;
fn extract_package(&self, pkg_path: &Path, output_dir: &Path) -> Result<()>;
diff --git a/syscare-build/src/package/rpm/mod.rs b/syscare-build/src/package/rpm/mod.rs
index 5b4bf07..0e9f77c 100644
--- a/syscare-build/src/package/rpm/mod.rs
+++ b/syscare-build/src/package/rpm/mod.rs
@@ -60,10 +60,6 @@ impl RpmPackage {
}
impl Package for RpmPackage {
- fn extension(&self) -> &'static str {
- PKG_FILE_EXT
- }
-
fn parse_package_info(&self, pkg_path: &Path) -> Result<PackageInfo> {
let query_result = Self::query_package_info(
pkg_path,
diff --git a/syscare-common/src/os/disk.rs b/syscare-common/src/os/disk.rs
deleted file mode 100644
index 7ace804..0000000
--- a/syscare-common/src/os/disk.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-// SPDX-License-Identifier: Mulan PSL v2
-/*
- * Copyright (c) 2024 Huawei Technologies Co., Ltd.
- * syscare-common is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- *
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-
-use std::ffi::OsStr;
-use std::path::{Path, PathBuf};
-
-use crate::fs;
-
-#[inline(always)]
-fn find_disk<P: AsRef<Path>, S: AsRef<OsStr>>(directory: P, name: S) -> std::io::Result<PathBuf> {
- #[inline(always)]
- fn __find_disk(directory: &Path, name: &OsStr) -> std::io::Result<PathBuf> {
- let dev = fs::find_symlink(
- directory,
- name,
- fs::FindOptions {
- fuzz: false,
- recursive: false,
- },
- )?;
- fs::canonicalize(dev)
- }
-
- __find_disk(directory.as_ref(), name.as_ref()).map_err(|_| {
- std::io::Error::new(
- std::io::ErrorKind::NotFound,
- format!(
- "Cannot find block device by label \"{}\"",
- name.as_ref().to_string_lossy()
- ),
- )
- })
-}
-
-pub fn find_by_id<S: AsRef<OsStr>>(name: S) -> std::io::Result<PathBuf> {
- find_disk("/dev/disk/by-id", name)
-}
-
-pub fn find_by_label<S: AsRef<OsStr>>(name: S) -> std::io::Result<PathBuf> {
- find_disk("/dev/disk/by-label", name)
-}
-
-pub fn find_by_uuid<S: AsRef<OsStr>>(name: S) -> std::io::Result<PathBuf> {
- find_disk("/dev/disk/by-uuid", name)
-}
-
-pub fn find_by_partuuid<S: AsRef<OsStr>>(name: S) -> std::io::Result<PathBuf> {
- find_disk("/dev/disk/by-partuuid", name)
-}
-
-pub fn find_by_path<S: AsRef<OsStr>>(name: S) -> std::io::Result<PathBuf> {
- find_disk("/dev/disk/by-path", name)
-}
diff --git a/syscare-common/src/os/grub.rs b/syscare-common/src/os/grub.rs
deleted file mode 100644
index 54299d8..0000000
--- a/syscare-common/src/os/grub.rs
+++ /dev/null
@@ -1,312 +0,0 @@
-// SPDX-License-Identifier: Mulan PSL v2
-/*
- * Copyright (c) 2024 Huawei Technologies Co., Ltd.
- * syscare-common is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- *
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-
-use std::collections::HashMap;
-use std::ffi::{OsStr, OsString};
-use std::io::{BufRead, BufReader};
-use std::os::unix::prelude::OsStrExt as StdOsStrExt;
-use std::path::{Path, PathBuf};
-
-use lazy_static::lazy_static;
-use log::debug;
-use regex::bytes::Regex;
-
-use super::{disk, proc_mounts};
-use crate::{
- ffi::OsStrExt,
- fs,
- io::{BufReadOsLines, OsLines},
-};
-
-#[derive(Debug, Clone, Copy)]
-enum BootType {
- Csm,
- Uefi,
-}
-
-#[derive(Debug)]
-pub struct GrubMenuEntry {
- name: OsString,
- root: PathBuf,
- kernel: PathBuf,
- initrd: PathBuf,
-}
-
-impl GrubMenuEntry {
- pub fn get_name(&self) -> &OsStr {
- &self.name
- }
-
- pub fn get_root(&self) -> &Path {
- &self.root
- }
-
- pub fn get_kernel(&self) -> PathBuf {
- // Path is stripped by regular expression, thus, it would always start with '/'
- self.root.join(self.kernel.strip_prefix("/").unwrap())
- }
-
- pub fn get_initrd(&self) -> PathBuf {
- // Path is stripped by regular expression, thus, it would always start with '/'
- self.root.join(self.initrd.strip_prefix("/").unwrap())
- }
-}
-
-struct GrubConfigParser<R> {
- lines: OsLines<R>,
- is_matching: bool,
- entry_name: Option<OsString>,
- entry_root: Option<PathBuf>,
- entry_kernel: Option<PathBuf>,
- entry_initrd: Option<PathBuf>,
-}
-
-impl<R: BufRead> GrubConfigParser<R> {
- pub fn new(buf: R) -> Self {
- Self {
- lines: buf.os_lines(),
- is_matching: false,
- entry_name: None,
- entry_root: None,
- entry_kernel: None,
- entry_initrd: None,
- }
- }
-
- #[inline(always)]
- fn parse_name(str: &OsStr) -> Option<OsString> {
- lazy_static! {
- static ref RE: Regex = Regex::new(r"'([^']*)'").unwrap();
- }
- RE.captures(str.as_bytes())
- .and_then(|captures| captures.get(1))
- .map(|matched| OsStr::from_bytes(matched.as_bytes()).to_os_string())
- }
-
- #[inline(always)]
- fn parse_uuid(str: &OsStr) -> Option<OsString> {
- str.split_whitespace()
- .filter_map(|str| {
- let arg = str.trim();
- if arg != OsStr::new("search") && !arg.starts_with("--") {
- return Some(arg.to_os_string());
- }
- None
- })
- .next()
- }
-
- #[inline(always)]
- fn parse_path(str: &OsStr) -> Option<PathBuf> {
- lazy_static! {
- static ref RE: Regex = Regex::new(r"/\.?\w+([\w\-\.])*").unwrap();
- }
- RE.find(str.as_bytes())
- .map(|matched| PathBuf::from(OsStr::from_bytes(matched.as_bytes())))
- }
-
- #[inline(always)]
- fn parse_mount_point(str: &OsStr) -> Option<PathBuf> {
- let find_dev = Self::parse_uuid(str).and_then(|uuid| disk::find_by_uuid(uuid).ok());
- if let (Some(dev_name), Ok(mounts)) = (find_dev, proc_mounts::Mounts::new()) {
- for mount in mounts {
- if mount.mount_source == dev_name {
- return Some(mount.mount_point);
- }
- }
- }
- None
- }
-}
-
-impl<R: BufRead> Iterator for GrubConfigParser<R> {
- type Item = GrubMenuEntry;
-
- fn next(&mut self) -> Option<Self::Item> {
- for line in (&mut self.lines).flatten() {
- if line.starts_with("#") {
- continue;
- }
-
- let str = line.trim();
- if str.is_empty() {
- continue;
- }
-
- if !self.is_matching {
- if str.starts_with("menuentry '") {
- self.entry_name = Self::parse_name(str);
- self.is_matching = true;
- }
- continue;
- }
- if str.starts_with("search") {
- self.entry_root = Self::parse_mount_point(str);
- } else if str.starts_with("linux") {
- self.entry_kernel = Self::parse_path(str);
- } else if str.starts_with("initrd") {
- self.entry_initrd = Self::parse_path(str);
- } else if str.starts_with("}") {
- let entry = match (
- &self.entry_name,
- &self.entry_root,
- &self.entry_kernel,
- &self.entry_initrd,
- ) {
- (Some(name), Some(root), Some(kernel), Some(initrd)) => Some(GrubMenuEntry {
- name: name.to_os_string(),
- root: root.to_path_buf(),
- kernel: kernel.to_path_buf(),
- initrd: initrd.to_path_buf(),
- }),
- _ => None,
- };
- self.is_matching = false;
- self.entry_name = None;
- self.entry_root = None;
- self.entry_kernel = None;
- self.entry_initrd = None;
-
- return entry;
- }
- }
- None
- }
-}
-
-struct GrubEnvParser<R> {
- lines: OsLines<R>,
-}
-
-impl<R: BufRead> GrubEnvParser<R> {
- pub fn new(buf: R) -> Self {
- Self {
- lines: buf.os_lines(),
- }
- }
-}
-
-impl<R: BufRead> Iterator for GrubEnvParser<R> {
- type Item = (OsString, OsString);
-
- fn next(&mut self) -> Option<Self::Item> {
- for line in (&mut self.lines).flatten() {
- if line.starts_with("#") {
- continue;
- }
-
- let str = line.trim();
- if str.is_empty() {
- continue;
- }
-
- let mut kv = line.split('=');
- if let (Some(key), Some(value)) = (kv.next(), kv.next()) {
- return Some((key.trim().to_os_string(), value.trim().to_os_string()));
- }
- }
-
- None
- }
-}
-
-fn get_boot_type() -> BootType {
- const UEFI_SYS_INTERFACE: &str = "/sys/firmware/efi";
-
- match fs::metadata(UEFI_SYS_INTERFACE) {
- Ok(_) => BootType::Uefi,
- Err(_) => BootType::Csm,
- }
-}
-
-fn get_grub_path(boot_type: BootType) -> PathBuf {
- const CSM_GRUB_PATH: &str = "/boot/grub2";
- const UEFI_GRUB_PATH: &str = "/boot/efi/EFI";
-
- match boot_type {
- BootType::Csm => PathBuf::from(CSM_GRUB_PATH),
- BootType::Uefi => PathBuf::from(UEFI_GRUB_PATH),
- }
-}
-
-fn find_grub_config<P: AsRef<Path>>(grub_root: P) -> std::io::Result<PathBuf> {
- const GRUB_CFG_NAME: &str = "grub.cfg";
-
- fs::find_file(
- grub_root,
- GRUB_CFG_NAME,
- fs::FindOptions {
- fuzz: false,
- recursive: true,
- },
- )
-}
-
-fn find_grub_env<P: AsRef<Path>>(grub_root: P) -> std::io::Result<PathBuf> {
- const GRUB_ENV_NAME: &str = "grubenv";
-
- fs::find_file(
- grub_root,
- GRUB_ENV_NAME,
- fs::FindOptions {
- fuzz: false,
- recursive: true,
- },
- )
-}
-
-pub fn read_menu_entries<P: AsRef<Path>>(grub_root: P) -> std::io::Result<Vec<GrubMenuEntry>> {
- let grub_config = find_grub_config(grub_root)?;
-
- let result = GrubConfigParser::new(BufReader::new(fs::open_file(grub_config)?)).collect();
-
- Ok(result)
-}
-
-pub fn read_grub_env<P: AsRef<Path>>(grub_root: P) -> std::io::Result<HashMap<OsString, OsString>> {
- let grub_env = find_grub_env(grub_root).unwrap();
-
- let result = GrubEnvParser::new(BufReader::new(fs::open_file(grub_env)?)).collect();
-
- Ok(result)
-}
-
-pub fn get_boot_entry() -> std::io::Result<GrubMenuEntry> {
- let boot_type = get_boot_type();
- let grub_root = get_grub_path(boot_type);
- debug!("Boot type: {:?}", boot_type);
-
- let menu_entries = read_menu_entries(&grub_root)?;
- debug!("Boot entries: {:#?}", menu_entries);
-
- let grub_env = read_grub_env(&grub_root)?;
- let default_entry_name = grub_env.get(OsStr::new("saved_entry")).ok_or_else(|| {
- std::io::Error::new(
- std::io::ErrorKind::Other,
- "Cannot read grub default entry name",
- )
- })?;
- debug!("Default entry: {:?}", default_entry_name);
-
- for entry in menu_entries {
- if entry.get_name() == default_entry_name {
- return Ok(entry);
- }
- }
-
- Err(std::io::Error::new(
- std::io::ErrorKind::Other,
- format!("Cannot find grub default entry {:?}", default_entry_name),
- ))
-}
diff --git a/syscare-common/src/os/kernel.rs b/syscare-common/src/os/kernel.rs
index b89850b..a29e663 100644
--- a/syscare-common/src/os/kernel.rs
+++ b/syscare-common/src/os/kernel.rs
@@ -12,51 +12,10 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{ffi::OsStr, path::Path};
-
-use anyhow::Result;
-
-const KEXEC_PATH: &str = "kexec";
-const SYSTEMCTL_PATH: &str = "systemctl";
+use std::ffi::OsStr;
use super::platform;
-use crate::{concat_os, process::Command};
pub fn version() -> &'static OsStr {
platform::release()
}
-
-pub fn load<P, Q>(kernel: P, initramfs: Q) -> Result<()>
-where
- P: AsRef<Path>,
- Q: AsRef<Path>,
-{
- Command::new(KEXEC_PATH)
- .arg("--load")
- .arg(kernel.as_ref())
- .arg(concat_os!("--initrd=", initramfs.as_ref()))
- .arg("--reuse-cmdline")
- .run_with_output()?
- .exit_ok()
-}
-
-pub fn unload() -> Result<()> {
- Command::new(KEXEC_PATH)
- .arg("--unload")
- .run_with_output()?
- .exit_ok()
-}
-
-pub fn systemd_exec() -> Result<()> {
- Command::new(SYSTEMCTL_PATH)
- .arg("kexec")
- .run_with_output()?
- .exit_ok()
-}
-
-pub fn force_exec() -> Result<()> {
- Command::new(KEXEC_PATH)
- .arg("--exec")
- .run_with_output()?
- .exit_ok()
-}
diff --git a/syscare-common/src/os/mod.rs b/syscare-common/src/os/mod.rs
index 8e6d5c1..6a93a20 100644
--- a/syscare-common/src/os/mod.rs
+++ b/syscare-common/src/os/mod.rs
@@ -13,8 +13,6 @@
*/
pub mod cpu;
-pub mod disk;
-pub mod grub;
pub mod kernel;
pub mod platform;
pub mod proc_maps;
diff --git a/syscare-common/src/util/digest.rs b/syscare-common/src/util/digest.rs
index bb879cb..086b636 100644
--- a/syscare-common/src/util/digest.rs
+++ b/syscare-common/src/util/digest.rs
@@ -45,10 +45,3 @@ where
Ok(format!("{:#x}", hasher.finalize()))
}
-
-pub fn dir<P: AsRef<Path>>(directory: P) -> std::io::Result<String> {
- file_list(fs::list_files(
- directory,
- fs::TraverseOptions { recursive: true },
- )?)
-}
diff --git a/syscared/src/fast_reboot/manager.rs b/syscared/src/fast_reboot/manager.rs
deleted file mode 100644
index 8a4a928..0000000
--- a/syscared/src/fast_reboot/manager.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: Mulan PSL v2
-/*
- * Copyright (c) 2024 Huawei Technologies Co., Ltd.
- * syscared is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- *
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-
-use std::path::PathBuf;
-
-use anyhow::{Context, Result};
-use lazy_static::lazy_static;
-use log::{error, info};
-
-use syscare_common::{
- fs,
- os::{grub, kernel},
-};
-
-lazy_static! {
- static ref BOOT_DIRECTORY: PathBuf = PathBuf::from("/boot");
-}
-
-pub enum RebootOption {
- Normal,
- Forced,
-}
-
-struct LoadKernelOption {
- name: String,
- kernel: PathBuf,
- initramfs: PathBuf,
-}
-
-pub struct KExecManager;
-
-impl KExecManager {
- fn find_kernel(kernel_version: &str) -> Result<LoadKernelOption> {
- info!("Finding kernel {}...", kernel_version);
- let kernel_file_name = format!("vmlinuz-{}", kernel_version);
- let kernel_file = fs::find_file(
- BOOT_DIRECTORY.as_path(),
- kernel_file_name,
- fs::FindOptions {
- fuzz: false,
- recursive: false,
- },
- )
- .with_context(|| format!("Cannot find kernel {}", kernel_version))?;
-
- info!("Finding initramfs...");
- let initramfs_file_name = format!("initramfs-{}.img", kernel_version);
- let initramfs_file = fs::find_file(
- BOOT_DIRECTORY.as_path(),
- initramfs_file_name,
- fs::FindOptions {
- fuzz: false,
- recursive: false,
- },
- )
- .with_context(|| format!("Cannot find kernel {} initramfs", kernel_version))?;
-
- Ok(LoadKernelOption {
- name: kernel_version.to_owned(),
- kernel: kernel_file,
- initramfs: initramfs_file,
- })
- }
-
- fn find_kernel_by_grub() -> Result<LoadKernelOption> {
- info!("Parsing grub configuration...");
- let entry = grub::get_boot_entry().context("Failed to read grub boot entry")?;
- let entry_name = entry
- .get_name()
- .to_str()
- .context("Failed to parse grub entry name")?;
-
- Ok(LoadKernelOption {
- name: entry_name.to_owned(),
- kernel: entry.get_kernel(),
- initramfs: entry.get_initrd(),
- })
- }
-
- pub fn load_kernel(kernel_version: Option<String>) -> Result<()> {
- let load_option = match kernel_version {
- Some(version) => Self::find_kernel(&version),
- None => Self::find_kernel_by_grub().or_else(|e| {
- error!("{:?}", e);
- let version: &str = kernel::version()
- .to_str()
- .context("Failed to parse current kernel version")?;
-
- Self::find_kernel(version)
- }),
- }?;
-
- kernel::unload().context("Failed to unload kernel")?;
-
- let name = load_option.name;
- let kernel = load_option.kernel;
- let initramfs = load_option.initramfs;
- info!("Loading {:?}", name);
- info!("Using kernel: {:?}", kernel);
- info!("Using initrd: {:?}", initramfs);
-
- kernel::load(&kernel, &initramfs).context("Failed to load kernel")
- }
-
- pub fn execute(option: RebootOption) -> Result<()> {
- match option {
- RebootOption::Normal => kernel::systemd_exec(),
- RebootOption::Forced => kernel::force_exec(),
- }
- .context("Failed to execute kernel")
- }
-}
diff --git a/syscared/src/fast_reboot/mod.rs b/syscared/src/fast_reboot/mod.rs
deleted file mode 100644
index 8c40eb9..0000000
--- a/syscared/src/fast_reboot/mod.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: Mulan PSL v2
-/*
- * Copyright (c) 2024 Huawei Technologies Co., Ltd.
- * syscared is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- *
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-
-mod manager;
-
-pub use manager::*;
diff --git a/syscared/src/main.rs b/syscared/src/main.rs
index 5c60ecf..f13a9f8 100644
--- a/syscared/src/main.rs
+++ b/syscared/src/main.rs
@@ -32,17 +32,13 @@ use syscare_common::{concat_os, fs, os};
mod args;
mod config;
-mod fast_reboot;
mod patch;
mod rpc;
use args::Arguments;
use config::Config;
use patch::monitor::PatchMonitor;
-use rpc::{
- skeleton::{FastRebootSkeleton, PatchSkeleton},
- skeleton_impl::{FastRebootSkeletonImpl, PatchSkeletonImpl},
-};
+use rpc::{skeleton::PatchSkeleton, skeleton_impl::PatchSkeletonImpl};
const DAEMON_NAME: &str = env!("CARGO_PKG_NAME");
const DAEMON_VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -195,7 +191,6 @@ impl Daemon {
let mut io_handler = IoHandler::new();
io_handler.extend_with(PatchSkeletonImpl::new(patch_manager).to_delegate());
- io_handler.extend_with(FastRebootSkeletonImpl.to_delegate());
Ok(io_handler)
}
diff --git a/syscared/src/rpc/skeleton/fast_reboot.rs b/syscared/src/rpc/skeleton/fast_reboot.rs
deleted file mode 100644
index 1a7b496..0000000
--- a/syscared/src/rpc/skeleton/fast_reboot.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: Mulan PSL v2
-/*
- * Copyright (c) 2024 Huawei Technologies Co., Ltd.
- * syscared is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- *
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-
-use super::function::{rpc, RpcResult};
-
-#[rpc(server)]
-pub trait FastRebootSkeleton {
- #[rpc(name = "fast_reboot")]
- fn fast_reboot(&self, kernel_version: Option<String>, force: bool) -> RpcResult<()>;
-}
diff --git a/syscared/src/rpc/skeleton/mod.rs b/syscared/src/rpc/skeleton/mod.rs
index 74456ca..6fa6b60 100644
--- a/syscared/src/rpc/skeleton/mod.rs
+++ b/syscared/src/rpc/skeleton/mod.rs
@@ -14,8 +14,6 @@
use super::function;
-mod fast_reboot;
mod patch;
-pub use fast_reboot::*;
pub use patch::*;
diff --git a/syscared/src/rpc/skeleton_impl/fast_reboot.rs b/syscared/src/rpc/skeleton_impl/fast_reboot.rs
deleted file mode 100644
index aeab458..0000000
--- a/syscared/src/rpc/skeleton_impl/fast_reboot.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-License-Identifier: Mulan PSL v2
-/*
- * Copyright (c) 2024 Huawei Technologies Co., Ltd.
- * syscared is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- *
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- */
-
-use anyhow::{Context, Result};
-
-use crate::fast_reboot::{KExecManager, RebootOption};
-use log::info;
-
-use super::{
- function::{RpcFunction, RpcResult},
- skeleton::FastRebootSkeleton,
-};
-
-pub struct FastRebootSkeletonImpl;
-
-impl FastRebootSkeleton for FastRebootSkeletonImpl {
- fn fast_reboot(&self, kernel_version: Option<String>, force: bool) -> RpcResult<()> {
- RpcFunction::call(move || -> Result<()> {
- info!("Rebooting system...");
-
- KExecManager::load_kernel(kernel_version)
- .and_then(|_| {
- KExecManager::execute(match force {
- true => RebootOption::Forced,
- false => RebootOption::Normal,
- })
- })
- .context("Failed to reboot system")
- })
- }
-}
diff --git a/syscared/src/rpc/skeleton_impl/mod.rs b/syscared/src/rpc/skeleton_impl/mod.rs
index a238df4..7037946 100644
--- a/syscared/src/rpc/skeleton_impl/mod.rs
+++ b/syscared/src/rpc/skeleton_impl/mod.rs
@@ -15,8 +15,6 @@
use super::function;
use super::skeleton;
-mod fast_reboot;
mod patch;
-pub use fast_reboot::*;
pub use patch::*;
--
2.34.1

View File

@ -1,37 +0,0 @@
From c22716401d7f76ba6bccfa5ee2cbb694d298d385 Mon Sep 17 00:00:00 2001
From: liuxiaobo <liuxiaobo19@huawei.com>
Date: Fri, 31 May 2024 17:18:16 +0800
Subject: [PATCH] abi: reexport uuid
Signed-off-by: liuxiaobo <liuxiaobo19@huawei.com>
---
syscare-abi/Cargo.toml | 2 +-
syscare-abi/src/lib.rs | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/syscare-abi/Cargo.toml b/syscare-abi/Cargo.toml
index f086850..a3af2be 100644
--- a/syscare-abi/Cargo.toml
+++ b/syscare-abi/Cargo.toml
@@ -10,4 +10,4 @@ build = "build.rs"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
-uuid = { version = "0.8", features = ["v4"] }
+uuid = { version = "0.8", features = ["v4", "serde"] }
diff --git a/syscare-abi/src/lib.rs b/syscare-abi/src/lib.rs
index 6600099..881587c 100644
--- a/syscare-abi/src/lib.rs
+++ b/syscare-abi/src/lib.rs
@@ -12,6 +12,8 @@
* See the Mulan PSL v2 for more details.
*/
+pub use uuid::Uuid;
+
mod package_info;
mod patch_info;
mod patch_status;
--
2.34.1

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@
From f913658fd6746bb59df82e0c564b664592e71c87 Mon Sep 17 00:00:00 2001
From: liuxiaobo <liuxiaobo19@huawei.com>
Date: Wed, 5 Jun 2024 10:52:44 +0800
Subject: [PATCH] common: fix 'failed to set selinux status' issue
Signed-off-by: liuxiaobo <liuxiaobo19@huawei.com>
---
syscare-common/src/os/selinux.rs | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/syscare-common/src/os/selinux.rs b/syscare-common/src/os/selinux.rs
index cf3b5b2..bb9864c 100644
--- a/syscare-common/src/os/selinux.rs
+++ b/syscare-common/src/os/selinux.rs
@@ -59,7 +59,13 @@ pub fn set_status(value: Status) -> Result<()> {
if (value != Status::Permissive) && (value != Status::Enforcing) {
bail!("Status {} is invalid", value);
}
- fs::write(SELINUX_SYS_FILE, value.to_string())?;
+ fs::write(
+ SELINUX_SYS_FILE,
+ match value {
+ Status::Enforcing => "1",
+ _ => "0",
+ },
+ )?;
Ok(())
}
--
2.34.1

View File

@ -1,48 +0,0 @@
From 7e17420b259d6a25425230cd1cc25bfaf602f1df Mon Sep 17 00:00:00 2001
From: ningyu <ningyu9@huawei.com>
Date: Mon, 27 May 2024 10:34:00 +0000
Subject: [PATCH] upatch-diff: exit with error when any tls var included
Signed-off-by: ningyu <ningyu9@huawei.com>
---
upatch-diff/create-diff-object.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/upatch-diff/create-diff-object.c b/upatch-diff/create-diff-object.c
index 6474b22..5ec6f31 100644
--- a/upatch-diff/create-diff-object.c
+++ b/upatch-diff/create-diff-object.c
@@ -847,6 +847,19 @@ static void include_debug_sections(struct upatch_elf *uelf)
/* currently, there si no special section need to be handled */
static void process_special_sections(void) {}
+static bool has_tls_included(struct upatch_elf *uelf)
+{
+ struct symbol *sym;
+
+ list_for_each_entry(sym, &uelf->symbols, list) {
+ if (sym->include == 1 && sym->type == STT_TLS) {
+ log_normal("TLS symbol '%s' included, but it's not supported", sym->name);
+ return true;
+ }
+ }
+ return false;
+}
+
static void verify_patchability(struct upatch_elf *uelf)
{
struct section *sec;
@@ -878,6 +891,10 @@ static void verify_patchability(struct upatch_elf *uelf)
if (errs)
DIFF_FATAL("%d, Unsupported section changes", errs);
+
+ if (has_tls_included(uelf)) {
+ DIFF_FATAL("Unsupported symbol included");
+ }
}
static void migrate_included_elements(struct upatch_elf *uelf_patched, struct upatch_elf *uelf_out)
--
2.34.1

View File

@ -1,34 +0,0 @@
From 8a12d289a01988ec7e2de11ff7f697f63ef74987 Mon Sep 17 00:00:00 2001
From: ningyu <ningyu9@huawei.com>
Date: Mon, 27 May 2024 11:16:26 +0000
Subject: [PATCH] upatch-diff: fix lookup_relf duplicate failure
Signed-off-by: ningyu <ningyu9@huawei.com>
---
upatch-diff/running-elf.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c
index 25b72b7..18ff095 100644
--- a/upatch-diff/running-elf.c
+++ b/upatch-diff/running-elf.c
@@ -125,9 +125,15 @@ bool lookup_relf(struct running_elf *relf,
symbol = &relf->obj_syms[i];
sympos++;
- if (strcmp(symbol->name, lookup_sym->name) != 0) {
+ if (result->symbol != NULL && symbol->type == STT_FILE) {
+ break;
+ }
+
+ if (strcmp(symbol->name, lookup_sym->name) != 0 ||
+ symbol->bind != lookup_sym->bind) {
continue;
}
+
if ((result->symbol != NULL) &&
(result->symbol->bind == symbol->bind)) {
ERROR("Found duplicate symbol '%s' in %s",
--
2.34.1

View File

@ -1,611 +0,0 @@
From e6eef4077acbff6e43e3c3880fb57d64b73e2567 Mon Sep 17 00:00:00 2001
From: liuxiaobo <liuxiaobo19@huawei.com>
Date: Thu, 27 Jun 2024 14:22:53 +0800
Subject: [PATCH] upatch-diff: fix memory leak
Signed-off-by: liuxiaobo <liuxiaobo19@huawei.com>
---
upatch-diff/create-diff-object.c | 34 +++++---
upatch-diff/elf-correlate.c | 10 +--
upatch-diff/elf-create.c | 83 ++++++++++++--------
upatch-diff/elf-debug.c | 7 +-
upatch-diff/running-elf.c | 2 +-
upatch-diff/running-elf.h | 2 +-
upatch-diff/upatch-elf.c | 128 ++++++++++++++++++++++---------
upatch-diff/upatch-elf.h | 14 +++-
8 files changed, 191 insertions(+), 89 deletions(-)
diff --git a/upatch-diff/create-diff-object.c b/upatch-diff/create-diff-object.c
index 5ec6f31..8830956 100644
--- a/upatch-diff/create-diff-object.c
+++ b/upatch-diff/create-diff-object.c
@@ -836,8 +836,10 @@ static void include_debug_sections(struct upatch_elf *uelf)
list_for_each_entry_safe(rela, saferela, &sec->relas, list)
// The shndex of symbol is SHN_COMMON, there is no related section
- if (rela->sym && !rela->sym->include)
+ if (rela->sym && !rela->sym->include) {
list_del(&rela->list);
+ free(rela);
+ }
}
if (eh_sec)
@@ -993,15 +995,20 @@ int main(int argc, char*argv[])
mark_ignored_functions_same();
mark_ignored_sections_same();
- upatch_elf_teardown(&uelf_source);
- upatch_elf_free(&uelf_source);
-
include_standard_elements(&uelf_patched);
num_changed = include_changed_functions(&uelf_patched);
new_globals_exist = include_new_globals(&uelf_patched);
if (!num_changed && !new_globals_exist) {
log_normal("No functional changes\n");
+ upatch_elf_destroy(&uelf_source);
+ upatch_elf_destroy(&uelf_patched);
+
+ upatch_elf_close(&uelf_source);
+ upatch_elf_close(&uelf_patched);
+
+ relf_close(&relf);
+
return 0;
}
@@ -1019,9 +1026,6 @@ int main(int argc, char*argv[])
migrate_included_elements(&uelf_patched, &uelf_out);
- /* since out elf still point to it, we only destroy it, not free it */
- upatch_elf_teardown(&uelf_patched);
-
upatch_create_strings_elements(&uelf_out);
upatch_create_patches_sections(&uelf_out, &relf);
@@ -1060,11 +1064,19 @@ int main(int argc, char*argv[])
upatch_write_output_elf(&uelf_out, uelf_patched.elf, arguments.output_obj, 0664);
- relf_destroy(&relf);
- upatch_elf_free(&uelf_patched);
- upatch_elf_teardown(&uelf_out);
- upatch_elf_free(&uelf_out);
+ upatch_elf_destroy(&uelf_source);
+ upatch_elf_destroy(&uelf_patched);
+ upatch_elf_destroy(&uelf_out);
+
+ upatch_elf_close(&uelf_source);
+ upatch_elf_close(&uelf_patched);
+ upatch_elf_close(&uelf_out);
+
+ relf_close(&relf);
log_normal("Done\n");
+ fflush(stdout);
+ fflush(stderr);
+
return 0;
}
diff --git a/upatch-diff/elf-correlate.c b/upatch-diff/elf-correlate.c
index 3e3a536..cc3b925 100644
--- a/upatch-diff/elf-correlate.c
+++ b/upatch-diff/elf-correlate.c
@@ -36,9 +36,8 @@ static void correlate_symbol(struct symbol *sym_orig, struct symbol *sym_patched
sym_orig->status = sym_patched->status = SAME;
if (strcmp(sym_orig->name, sym_patched->name)) {
log_debug("renaming symbol %s to %s \n", sym_patched->name, sym_orig->name);
- sym_patched->name = strdup(sym_orig->name);
- if (!sym_patched->name)
- ERROR("strdup");
+ sym_patched->name = sym_orig->name;
+ sym_patched->name_source = DATA_SOURCE_REF;
}
if (sym_orig->relf_sym && !sym_patched->relf_sym)
sym_patched->relf_sym = sym_orig->relf_sym;
@@ -98,9 +97,8 @@ static void __correlate_section(struct section *sec_orig, struct section *sec_pa
/* Make sure these two sections have the same name */
if (strcmp(sec_orig->name, sec_patched->name)) {
log_debug("renaming section %s to %s \n", sec_patched->name, sec_orig->name);
- sec_patched->name = strdup(sec_orig->name);
- if (!sec_patched->name)
- ERROR("strdup");
+ sec_patched->name = sec_orig->name;
+ sec_patched->name_source = DATA_SOURCE_REF;
}
}
diff --git a/upatch-diff/elf-create.c b/upatch-diff/elf-create.c
index 8ac212a..bd7edf0 100644
--- a/upatch-diff/elf-create.c
+++ b/upatch-diff/elf-create.c
@@ -41,10 +41,12 @@ static struct section *create_section_pair(struct upatch_elf *uelf, char *name,
{
char *relaname;
struct section *sec, *relasec;
+ size_t size = strlen(name) + strlen(".rela") + 1;
- relaname = malloc(strlen(name) + strlen(".rela") + 1);
- if (!relaname)
+ relaname = calloc(1, size);
+ if (!relaname) {
ERROR("relaname malloc failed.");
+ }
strcpy(relaname, ".rela");
strcat(relaname, name);
@@ -52,13 +54,17 @@ static struct section *create_section_pair(struct upatch_elf *uelf, char *name,
/* allocate text section resourcce */
ALLOC_LINK(sec, &uelf->sections);
sec->name = name;
- sec->data = malloc(sizeof(*sec->data));
- if (!sec->data)
+ sec->data = calloc(1, sizeof(Elf_Data));
+ if (!sec->data) {
ERROR("section data malloc failed.");
+ }
+ sec->data_source = DATA_SOURCE_ALLOC;
sec->data->d_buf = calloc(nr, entsize);
- if (!sec->data->d_buf)
+ if (!sec->data->d_buf) {
ERROR("d_buf of section data malloc failed.");
+ }
+ sec->dbuf_source = DATA_SOURCE_ALLOC;
sec->data->d_size = entsize * nr;
sec->data->d_type = ELF_T_BYTE;
@@ -73,12 +79,15 @@ static struct section *create_section_pair(struct upatch_elf *uelf, char *name,
/* set relocation section */
ALLOC_LINK(relasec, &uelf->sections);
relasec->name = relaname;
+ relasec->name_source = DATA_SOURCE_ALLOC;
INIT_LIST_HEAD(&relasec->relas);
/* buffers will be generated by upatch_rebuild_rela_section_data */
- relasec->data = malloc(sizeof(*relasec->data));
- if (!relasec->data)
+ relasec->data = calloc(1, sizeof(Elf_Data));
+ if (!relasec->data) {
ERROR("relasec data malloc failed.");
+ }
+ relasec->data_source = DATA_SOURCE_ALLOC;
relasec->data->d_type = ELF_T_RELA;
@@ -103,9 +112,12 @@ void upatch_create_strings_elements(struct upatch_elf *uelf)
ALLOC_LINK(sec, &uelf->sections);
sec->name = ".upatch.strings";
- sec->data = malloc(sizeof(*sec->data));
- if (!sec->data)
+ sec->data = calloc(1, sizeof(Elf_Data));
+ if (!sec->data) {
ERROR("section data malloc failed");
+ }
+ sec->data_source = DATA_SOURCE_ALLOC;
+
sec->data->d_type = ELF_T_BYTE;
/* set section header */
@@ -310,12 +322,14 @@ void upatch_build_strings_section_data(struct upatch_elf *uelf)
size += strlen(string->name) + 1;
/* allocate section resources */
- strtab = malloc(size);
- if (!strtab)
+ strtab = calloc(1, size);
+ if (!strtab) {
ERROR("strtab malloc failed.");
+ }
sec->data->d_buf = strtab;
sec->data->d_size = size;
+ sec->dbuf_source = DATA_SOURCE_ALLOC;
/* populate strings section data */
list_for_each_entry(string, &uelf->strings, list) {
@@ -407,13 +421,15 @@ static void rebuild_rela_section_data(struct section *sec)
nr++;
size = nr * sizeof(*relas);
- relas = malloc(size);
- if (!relas)
+ relas = calloc(1, size);
+ if (!relas) {
ERROR("relas malloc failed.");
+ }
sec->data->d_buf = relas;
sec->data->d_size = size;
sec->sh.sh_size = size;
+ sec->dbuf_source = DATA_SOURCE_ALLOC;
list_for_each_entry(rela, &sec->relas, list) {
relas[index].r_offset = rela->offset;
@@ -469,18 +485,19 @@ void upatch_create_shstrtab(struct upatch_elf *uelf)
char *buf;
shstrtab = find_section_by_name(&uelf->sections, ".shstrtab");
- if (!shstrtab)
+ if (!shstrtab) {
ERROR("find_section_by_name failed.");
+ }
/* determine size of string table */
size = 1;
list_for_each_entry(sec, &uelf->sections, list)
size += strlen(sec->name) + 1;
- buf = malloc(size);
- if (!buf)
+ buf = calloc(1, size);
+ if (!buf) {
ERROR("malloc shstrtab failed.");
- memset(buf, 0, size);
+ }
offset = 1;
list_for_each_entry(sec, &uelf->sections, list) {
@@ -490,11 +507,14 @@ void upatch_create_shstrtab(struct upatch_elf *uelf)
offset += len;
}
- if (offset != size)
+ if (offset != size) {
+ free(buf);
ERROR("shstrtab size mismatch.");
+ }
shstrtab->data->d_buf = buf;
shstrtab->data->d_size = size;
+ shstrtab->dbuf_source = DATA_SOURCE_ALLOC;
log_debug("shstrtab: ");
print_strtab(buf, size);
@@ -506,25 +526,24 @@ void upatch_create_shstrtab(struct upatch_elf *uelf)
void upatch_create_strtab(struct upatch_elf *uelf)
{
- struct section *strtab;
- struct symbol *sym;
size_t size = 0, offset = 0, len = 0;
- char *buf;
- strtab = find_section_by_name(&uelf->sections, ".strtab");
- if (!strtab)
+ struct section *strtab = find_section_by_name(&uelf->sections, ".strtab");
+ if (!strtab) {
ERROR("find section failed in create strtab.");
+ }
+ struct symbol *sym = NULL;
list_for_each_entry(sym, &uelf->symbols, list) {
if (sym->type == STT_SECTION)
continue;
size += strlen(sym->name) + 1;
}
- buf = malloc(size);
- if (!buf)
+ char *buf = calloc(1, size);
+ if (!buf) {
ERROR("malloc buf failed in create strtab");
- memset(buf, 0, size);
+ }
list_for_each_entry(sym, &uelf->symbols, list) {
if (sym->type == STT_SECTION) {
@@ -537,11 +556,14 @@ void upatch_create_strtab(struct upatch_elf *uelf)
offset += len;
}
- if (offset != size)
+ if (offset != size) {
+ free(buf);
ERROR("shstrtab size mismatch.");
+ }
strtab->data->d_buf = buf;
strtab->data->d_size = size;
+ strtab->dbuf_source = DATA_SOURCE_ALLOC;
log_debug("strtab: ");
print_strtab(buf, size);
@@ -569,10 +591,10 @@ void upatch_create_symtab(struct upatch_elf *uelf)
nr++;
size = nr * symtab->sh.sh_entsize;
- buf = malloc(size);
- if (!buf)
+ buf = calloc(1, size);
+ if (!buf) {
ERROR("malloc buf failed in create symtab.");
- memset(buf, 0, size);
+ }
offset = 0;
list_for_each_entry(sym, &uelf->symbols, list) {
@@ -585,6 +607,7 @@ void upatch_create_symtab(struct upatch_elf *uelf)
symtab->data->d_buf = buf;
symtab->data->d_size = size;
+ symtab->dbuf_source = DATA_SOURCE_ALLOC;
/* update symtab section header */
strtab = find_section_by_name(&uelf->sections, ".strtab");
diff --git a/upatch-diff/elf-debug.c b/upatch-diff/elf-debug.c
index eaabfa1..0490f86 100644
--- a/upatch-diff/elf-debug.c
+++ b/upatch-diff/elf-debug.c
@@ -129,9 +129,10 @@ void upatch_rebuild_eh_frame(struct section *sec)
/* in this time, some relcation entries may have been deleted */
frame_size = 0;
- eh_frame = malloc(sec->data->d_size);
- if (!eh_frame)
+ eh_frame = calloc(1, sec->data->d_size);
+ if (!eh_frame) {
ERROR("malloc eh_frame failed \n");
+ }
/* 8 is the offset of PC begin */
current_offset = 8;
@@ -191,5 +192,7 @@ void upatch_rebuild_eh_frame(struct section *sec)
sec->data->d_buf = eh_frame;
sec->data->d_size = frame_size;
+ sec->dbuf_source = DATA_SOURCE_ALLOC;
+
sec->sh.sh_size = frame_size;
}
diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c
index 18ff095..c99b395 100644
--- a/upatch-diff/running-elf.c
+++ b/upatch-diff/running-elf.c
@@ -101,7 +101,7 @@ void relf_init(char *elf_name, struct running_elf *relf)
}
}
-int relf_destroy(struct running_elf *relf)
+int relf_close(struct running_elf *relf)
{
free(relf->obj_syms);
elf_end(relf->elf);
diff --git a/upatch-diff/running-elf.h b/upatch-diff/running-elf.h
index 0646780..b02c8e2 100644
--- a/upatch-diff/running-elf.h
+++ b/upatch-diff/running-elf.h
@@ -58,7 +58,7 @@ struct running_elf {
void relf_init(char *, struct running_elf *);
-int relf_destroy(struct running_elf *);
+int relf_close(struct running_elf *);
bool lookup_relf(struct running_elf *, struct symbol *, struct lookup_result *);
diff --git a/upatch-diff/upatch-elf.c b/upatch-diff/upatch-elf.c
index ee38efc..171e88e 100644
--- a/upatch-diff/upatch-elf.c
+++ b/upatch-diff/upatch-elf.c
@@ -67,11 +67,14 @@ static void create_section_list(struct upatch_elf *uelf)
sec->name = elf_strptr(uelf->elf, shstrndx, sec->sh.sh_name);
if (!sec->name)
ERROR("elf_strptr with error %s", elf_errmsg(0));
-
sec->data = elf_getdata(scn, NULL);
if (!sec->data)
ERROR("elf_getdata with error %s", elf_errmsg(0));
+ sec->name_source = DATA_SOURCE_ELF;
+ sec->data_source = DATA_SOURCE_ELF;
+ sec->dbuf_source = DATA_SOURCE_ELF;
+
sec->index = (unsigned int)elf_ndxscn(scn);
/* found extended section header */
if (sec->sh.sh_type == SHT_SYMTAB_SHNDX)
@@ -157,6 +160,8 @@ static void create_rela_list(struct upatch_elf *uelf, struct section *relasec)
struct rela *rela;
int index = 0, skip = 0;
+ INIT_LIST_HEAD(&relasec->relas);
+
/* for relocation sections, sh_info is the index which these informations apply */
relasec->base = find_section_by_index(&uelf->sections, relasec->sh.sh_info);
if (!relasec->base)
@@ -215,10 +220,86 @@ static void create_rela_list(struct upatch_elf *uelf, struct section *relasec)
}
}
+static void destroy_rela_list(struct section *relasec)
+{
+ struct rela *rela = NULL, *saferela = NULL;
+
+ list_for_each_entry_safe(rela, saferela, &relasec->relas, list) {
+ list_del(&rela->list);
+ free(rela);
+ }
+
+ INIT_LIST_HEAD(&relasec->relas);
+}
+
+static void destroy_section_list(struct upatch_elf *uelf)
+{
+ struct section *sec = NULL, *safesec = NULL;
+
+ list_for_each_entry_safe(sec, safesec, &uelf->sections, list) {
+ if (sec->twin) {
+ sec->twin->twin = NULL;
+ }
+
+ if ((sec->name != NULL) && (sec->name_source == DATA_SOURCE_ALLOC)) {
+ free(sec->name);
+ sec->name = NULL;
+ }
+
+ if (sec->data != NULL) {
+ if (sec->dbuf_source == DATA_SOURCE_ALLOC) {
+ free(sec->data->d_buf);
+ sec->data->d_buf = NULL;
+ }
+ if (sec->data_source == DATA_SOURCE_ALLOC) {
+ free(sec->data);
+ sec->data = NULL;
+ }
+ }
+
+ if (is_rela_section(sec)) {
+ destroy_rela_list(sec);
+ }
+
+ list_del(&sec->list);
+ free(sec);
+ }
+
+ INIT_LIST_HEAD(&uelf->sections);
+}
+
+static void destroy_symbol_list(struct upatch_elf *uelf)
+{
+ struct symbol *sym = NULL, *safesym = NULL;
+
+ list_for_each_entry_safe(sym, safesym, &uelf->symbols, list) {
+ if (sym->twin) {
+ sym->twin->twin = NULL;
+ }
+
+ list_del(&sym->list);
+ free(sym);
+ }
+
+ INIT_LIST_HEAD(&uelf->symbols);
+}
+
+static void destroy_string_list(struct upatch_elf *uelf)
+{
+ struct string *str = NULL, *safestr = NULL;
+
+ list_for_each_entry_safe(str, safestr, &uelf->strings, list) {
+ list_del(&str->list);
+ free(str);
+ }
+
+ INIT_LIST_HEAD(&uelf->strings);
+}
+
void upatch_elf_open(struct upatch_elf *uelf, const char *name)
{
GElf_Ehdr ehdr;
- struct section *relasec;
+ struct section *sec;
Elf *elf = NULL;
int fd = 1;
@@ -264,46 +345,21 @@ void upatch_elf_open(struct upatch_elf *uelf, const char *name)
create_section_list(uelf);
create_symbol_list(uelf);
- list_for_each_entry(relasec, &uelf->sections, list) {
- if (!is_rela_section(relasec))
- continue;
- INIT_LIST_HEAD(&relasec->relas);
-
- create_rela_list(uelf, relasec);
- }
-}
-
-void upatch_elf_teardown(struct upatch_elf *uelf)
-{
- struct section *sec, *safesec;
- struct symbol *sym, *safesym;
- struct rela *rela, *saferela;
-
- list_for_each_entry_safe(sec, safesec, &uelf->sections, list) {
- if (sec->twin)
- sec->twin->twin = NULL;
+ list_for_each_entry(sec, &uelf->sections, list) {
if (is_rela_section(sec)) {
- list_for_each_entry_safe(rela, saferela, &sec->relas, list) {
- memset(rela, 0, sizeof(*rela));
- free(rela);
- }
+ create_rela_list(uelf, sec);
}
- memset(sec, 0, sizeof(*sec));
- free(sec);
- }
-
- list_for_each_entry_safe(sym, safesym, &uelf->symbols, list) {
- if (sym->twin)
- sym->twin->twin = NULL;
- memset(sym, 0, sizeof(*sym));
- free(sym);
}
+}
- INIT_LIST_HEAD(&uelf->sections);
- INIT_LIST_HEAD(&uelf->symbols);
+void upatch_elf_destroy(struct upatch_elf *uelf)
+{
+ destroy_section_list(uelf);
+ destroy_symbol_list(uelf);
+ destroy_string_list(uelf);
}
-void upatch_elf_free(struct upatch_elf *uelf)
+void upatch_elf_close(struct upatch_elf *uelf)
{
elf_end(uelf->elf);
close(uelf->fd);
diff --git a/upatch-diff/upatch-elf.h b/upatch-diff/upatch-elf.h
index 3cbb59b..6c62c93 100644
--- a/upatch-diff/upatch-elf.h
+++ b/upatch-diff/upatch-elf.h
@@ -39,6 +39,12 @@ struct section;
struct rela;
struct symbol;
+enum data_source {
+ DATA_SOURCE_ELF,
+ DATA_SOURCE_REF,
+ DATA_SOURCE_ALLOC,
+};
+
enum status {
NEW,
CHANGED,
@@ -61,6 +67,9 @@ struct section {
struct section *twin;
char *name;
Elf_Data *data;
+ enum data_source name_source;
+ enum data_source data_source;
+ enum data_source dbuf_source;
GElf_Shdr sh;
int ignore;
int include;
@@ -102,6 +111,7 @@ struct symbol {
struct section *sec;
GElf_Sym sym;
char *name;
+ enum data_source name_source;
struct debug_symbol *relf_sym;
unsigned int index;
unsigned char bind;
@@ -132,8 +142,8 @@ struct upatch_elf {
void upatch_elf_open(struct upatch_elf *, const char *);
// Destory upatch_elf struct
-void upatch_elf_teardown(struct upatch_elf *);
+void upatch_elf_destroy(struct upatch_elf *);
-void upatch_elf_free(struct upatch_elf *);
+void upatch_elf_close(struct upatch_elf *);
#endif
--
2.34.1

View File

@ -1,43 +0,0 @@
From a1fa8c08a6605339ac9cb5d9101f4f24c7430f62 Mon Sep 17 00:00:00 2001
From: liuxiaobo <liuxiaobo19@huawei.com>
Date: Thu, 27 Jun 2024 16:22:26 +0800
Subject: [PATCH] upatch-hijacker: fix memory leak
Signed-off-by: liuxiaobo <liuxiaobo19@huawei.com>
---
upatch-hijacker/hijacker/gnu-as-hijacker.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/upatch-hijacker/hijacker/gnu-as-hijacker.c b/upatch-hijacker/hijacker/gnu-as-hijacker.c
index 860a84f..886420e 100644
--- a/upatch-hijacker/hijacker/gnu-as-hijacker.c
+++ b/upatch-hijacker/hijacker/gnu-as-hijacker.c
@@ -48,6 +48,7 @@ int main(int argc, char *argv[], char *envp[])
{
// Try to get executable path
const char *filename = get_current_exec();
+
if (filename == NULL) {
return -ENOENT;
}
@@ -111,9 +112,15 @@ int main(int argc, char *argv[], char *envp[])
(void)unlink(output_file);
}
+ int ret = 0;
if (symlink(new_output_file, output_file) != 0) {
- return execve(filename, argv, envp);
+ ret = execve(filename, argv, envp);
+ goto out;
}
- return execve(filename, (char* const*)new_argv, envp);
+ ret = execve(filename, (char* const*)new_argv, envp);
+out:
+ free(new_argv);
+
+ return ret;
}
--
2.34.1

View File

@ -1,113 +0,0 @@
From 93a0c2c9d1ad383758b595fa551b43366d82d047 Mon Sep 17 00:00:00 2001
From: liuxiaobo <liuxiaobo19@huawei.com>
Date: Thu, 27 Jun 2024 16:22:02 +0800
Subject: [PATCH] upatch-manage: fix memory leak
Signed-off-by: liuxiaobo <liuxiaobo19@huawei.com>
---
upatch-manage/arch/x86_64/ptrace.c | 7 ++--
upatch-manage/upatch-process.c | 61 ++++++++++++++++++------------
2 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/upatch-manage/arch/x86_64/ptrace.c b/upatch-manage/arch/x86_64/ptrace.c
index 3d6dd72..95e2710 100644
--- a/upatch-manage/arch/x86_64/ptrace.c
+++ b/upatch-manage/arch/x86_64/ptrace.c
@@ -173,9 +173,8 @@ size_t get_upatch_addr_len()
return UPATCH_ADDR_LEN;
}
-
unsigned long get_new_insn(void)
{
- char jmp_insn[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00};
- return *(unsigned long *)jmp_insn;
-}
\ No newline at end of file
+ // ASM: jmp word ptr [di] (FF25 0000 0000 0000)
+ return 0x25FF;
+}
diff --git a/upatch-manage/upatch-process.c b/upatch-manage/upatch-process.c
index 3b8db3b..84ec030 100644
--- a/upatch-manage/upatch-process.c
+++ b/upatch-manage/upatch-process.c
@@ -385,6 +385,40 @@ process_new_object(struct upatch_process *proc, dev_t dev, ino_t inode,
return o;
}
+static int add_upatch_object(struct upatch_process *proc,
+ struct object_file *o, unsigned long src, unsigned char *header_buf)
+{
+ struct object_patch *opatch;
+
+ opatch = malloc(sizeof(struct object_patch));
+ if (opatch == NULL) {
+ log_error("malloc opatch failed\n");
+ return -1;
+ }
+
+ opatch->uinfo = malloc(sizeof(struct upatch_info));
+ if (opatch->uinfo == NULL) {
+ log_error("malloc opatch->uinfo failed\n");
+ free(opatch);
+ return -1;
+ }
+
+ memcpy(opatch->uinfo, header_buf, sizeof(struct upatch_info));
+ opatch->funcs = malloc(opatch->uinfo->changed_func_num *
+ sizeof(struct upatch_info_func));
+ if (upatch_process_mem_read(proc, src, opatch->funcs,
+ opatch->uinfo->changed_func_num * sizeof(struct upatch_info_func))) {
+ log_error("can't read patch funcs at 0x%lx\n", src);
+ free(opatch->uinfo);
+ free(opatch);
+ return -1;
+ }
+ list_add(&opatch->list, &o->applied_patch);
+ o->num_applied_patch++;
+ o->is_patch = 1;
+
+ return 0;
+}
/**
* Returns: 0 if everything is ok, -1 on error.
*/
@@ -420,33 +454,10 @@ static int process_add_object_vma(struct upatch_process *proc, dev_t dev,
}
if (object_type == OBJECT_UPATCH) {
- struct object_patch *opatch;
-
- opatch = malloc(sizeof(struct object_patch));
- if (opatch == NULL) {
- return -1;
- }
-
- opatch->uinfo = malloc(sizeof(struct upatch_info));
- if (opatch->uinfo == NULL) {
- return -1;
- }
-
- memcpy(opatch->uinfo, header_buf, sizeof(struct upatch_info));
- opatch->funcs = malloc(opatch->uinfo->changed_func_num *
- sizeof(struct upatch_info_func));
- if (upatch_process_mem_read(
- proc, vma->start + sizeof(struct upatch_info),
- opatch->funcs,
- opatch->uinfo->changed_func_num *
- sizeof(struct upatch_info_func))) {
- log_error("can't read patch funcs at 0x%lx\n",
- vma->start + sizeof(struct upatch_info));
+ unsigned long src = vma->start + sizeof(struct upatch_info);
+ if (add_upatch_object(proc, o, src, header_buf) != 0) {
return -1;
}
- list_add(&opatch->list, &o->applied_patch);
- o->num_applied_patch++;
- o->is_patch = 1;
}
if (object_type == OBJECT_ELF) {
o->is_elf = 1;
--
2.34.1

File diff suppressed because it is too large Load Diff

View File

@ -1,242 +0,0 @@
From c61c3e241f7a286df302a77ba6ed078dd56b9fb1 Mon Sep 17 00:00:00 2001
From: liuxiaobo <liuxiaobo19@huawei.com>
Date: Mon, 17 Jun 2024 16:22:08 +0800
Subject: [PATCH] all: implement asan & gcov build type
Signed-off-by: liuxiaobo <liuxiaobo19@huawei.com>
---
CMakeLists.txt | 127 ++++++++++++++++++++--------
upatch-diff/CMakeLists.txt | 4 +-
upatch-helper/helper/CMakeLists.txt | 4 +-
upatch-manage/CMakeLists.txt | 5 +-
4 files changed, 99 insertions(+), 41 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 659222f..04872b1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,12 @@ project(syscare)
include(GNUInstallDirs)
find_package(Git QUIET)
-# Version
+# Build type
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE RelWithDebInfo)
+endif()
+
+# Build version
if(NOT DEFINED BUILD_VERSION)
execute_process(
COMMAND sh -c "cat syscare/Cargo.toml | grep -F 'version' | head -n 1 | awk -F '\"' '{print $2}'"
@@ -27,12 +32,55 @@ if(GIT_FOUND)
ERROR_QUIET
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
- set(BUILD_VERSION "${BUILD_VERSION}-g${GIT_VERSION}")
+ set(PROJECT_BUILD_VERSION "${BUILD_VERSION}-g${GIT_VERSION}")
else()
- set(BUILD_VERSION "${BUILD_VERSION}")
+ set(PROJECT_BUILD_VERSION "${BUILD_VERSION}")
+endif()
+
+# Build configurations
+if(ENABLE_ASAN)
+ set(PROJECT_BUILD_VERSION "${PROJECT_BUILD_VERSION}-asan")
+ list(APPEND PROJECT_C_BUILD_FLAGS -fsanitize=address -fno-omit-frame-pointer)
+ list(APPEND PROJECT_C_LIBRARIES asan)
endif()
-# Set install directories
+if(ENABLE_GCOV)
+ set(PROJECT_BUILD_VERSION "${PROJECT_BUILD_VERSION}-gcov")
+ list(APPEND PROJECT_C_BUILD_FLAGS -ftest-coverage -fprofile-arcs)
+ list(APPEND PROJECT_RUST_FLAGS -C instrument-coverage)
+ list(APPEND PROJECT_C_LIBRARIES gcov)
+endif()
+
+# Build flags
+list(APPEND PROJECT_C_BUILD_FLAGS
+ -std=gnu99 -g -Wall -O2 -Werror -Wextra
+ -DBUILD_VERSION="${PROJECT_BUILD_VERSION}" -D_FORTIFY_SOURCE=2
+ -Wtrampolines -Wformat=2 -Wstrict-prototypes -Wdate-time
+ -Wstack-usage=8192 -Wfloat-equal -Wswitch-default
+ -Wshadow -Wconversion -Wcast-qual -Wcast-align -Wunused -Wundef
+ -funsigned-char -fstack-protector-all -fpic -fpie -ftrapv
+ -fstack-check -freg-struct-return -fno-canonical-system-headers
+ -pipe -fdebug-prefix-map=old=new
+)
+list(APPEND PROJECT_RUST_FLAGS
+ --cfg unsound_local_offset
+ -C relocation_model=pic
+ -D warnings
+ -C link-arg=-s
+ -C overflow_checks
+ -W rust_2021_incompatible_closure_captures
+)
+
+# Link flags
+list(APPEND PROJECT_C_LINK_FLAGS
+ -pie
+ -Wl,-z,relro,-z,now
+ -Wl,-z,noexecstack -rdynamic
+ -Wl,-Bsymbolic
+ -Wl,-no-undefined
+)
+
+# Install directories
set(SYSCARE_BINARY_DIR "${CMAKE_INSTALL_FULL_BINDIR}")
set(SYSCARE_LIBEXEC_DIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/syscare")
set(SYSCARE_SERVICE_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system")
@@ -46,48 +94,53 @@ message("╚════██║ ╚██╔╝ ╚════██║█
message("███████║ ██║ ███████║╚██████╗██║ ██║██║ ██║███████╗")
message("╚══════╝ ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝")
message("---------------------------------------------------------")
-message("-- Verion: ${BUILD_VERSION}")
+message("-- Verion: ${PROJECT_BUILD_VERSION}")
+message("-- Rust flags: ${PROJECT_RUST_FLAGS}")
+message("-- Build flags: ${PROJECT_C_BUILD_FLAGS}")
+message("-- Link flags: ${PROJECT_C_LINK_FLAGS}")
+message("-- Link libraries: ${PROJECT_C_LIBRARIES}")
message("-- Binary directory: ${SYSCARE_BINARY_DIR}")
message("-- Libexec directory: ${SYSCARE_LIBEXEC_DIR}")
message("-- Service directory: ${SYSCARE_SERVICE_DIR}")
message("---------------------------------------------------------")
-# Compile options
-add_compile_options(-DBUILD_VERSION="${BUILD_VERSION}")
-add_compile_options(-std=gnu99 -g -Wall -D_FORTIFY_SOURCE=2 -O2 -Werror -Wextra
- -Wtrampolines -Wformat=2 -Wstrict-prototypes -Wdate-time -Wstack-usage=8192
- -Wfloat-equal -Wswitch-default -Wshadow -Wconversion -Wcast-qual -Wcast-align
- -Wunused -Wundef -funsigned-char -fstack-protector-all -fpic -fpie -ftrapv
- -fstack-check -freg-struct-return -fno-canonical-system-headers -pipe
- -fdebug-prefix-map=old=new)
-set(LINK_FLAGS "-pie -Wl,-z,relro,-z,now -Wl,-z,noexecstack -rdynamic -Wl,-Bsymbolic -Wl,-no-undefined")
-set(CMAKE_SHARED_LINKER_FLAGS "${LINK_FLAGS}")
-set(CMAKE_EXE_LINKER_FLAGS "${LINK_FLAGS}")
-# Subdirectories
-add_subdirectory(upatch-diff)
-add_subdirectory(upatch-manage)
-add_subdirectory(upatch-helper)
-add_subdirectory(misc)
+# Apply all flags
+add_compile_options(${PROJECT_C_BUILD_FLAGS})
+add_link_options(${PROJECT_C_LINK_FLAGS})
+link_libraries(${PROJECT_C_LIBRARIES})
# Build rust executables
-add_custom_target(rust-executables ALL
+foreach(FLAG IN LISTS PROJECT_RUST_FLAGS)
+ set(RUSTFLAGS "${RUSTFLAGS} ${FLAG}")
+endforeach()
+
+add_custom_target(rust-build ALL
COMMENT "Building rust executables..."
COMMAND ${CMAKE_COMMAND} -E env
- "BUILD_VERSION=${BUILD_VERSION}"
- "RUSTFLAGS=--cfg unsound_local_offset -C relocation_model=pic -D warnings -C link-arg=-s -C overflow_checks -W rust_2021_incompatible_closure_captures"
- cargo build --release --target-dir ${CMAKE_CURRENT_BINARY_DIR}
+ "BUILD_VERSION=${PROJECT_BUILD_VERSION}"
+ "RUSTFLAGS=${RUSTFLAGS}"
+ cargo build --release --target-dir "${CMAKE_CURRENT_BINARY_DIR}/rust"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
# Install rust binaries
install(
PROGRAMS
- ${CMAKE_CURRENT_BINARY_DIR}/release/upatchd
- ${CMAKE_CURRENT_BINARY_DIR}/release/syscared
- ${CMAKE_CURRENT_BINARY_DIR}/release/syscare
+ ${CMAKE_CURRENT_BINARY_DIR}/rust/release/upatchd
+ ${CMAKE_CURRENT_BINARY_DIR}/rust/release/syscared
+ PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ DESTINATION
+ ${SYSCARE_BINARY_DIR}
+)
+
+install(
+ PROGRAMS
+ ${CMAKE_CURRENT_BINARY_DIR}/rust/release/syscare
PERMISSIONS
- OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
DESTINATION
${SYSCARE_BINARY_DIR}
@@ -95,12 +148,18 @@ install(
install(
PROGRAMS
- ${CMAKE_CURRENT_BINARY_DIR}/release/upatch-build
- ${CMAKE_CURRENT_BINARY_DIR}/release/syscare-build
+ ${CMAKE_CURRENT_BINARY_DIR}/rust/release/upatch-build
+ ${CMAKE_CURRENT_BINARY_DIR}/rust/release/syscare-build
PERMISSIONS
- OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
DESTINATION
${SYSCARE_LIBEXEC_DIR}
)
+
+# Build other components
+add_subdirectory(upatch-diff)
+add_subdirectory(upatch-manage)
+add_subdirectory(upatch-helper)
+add_subdirectory(misc)
diff --git a/upatch-diff/CMakeLists.txt b/upatch-diff/CMakeLists.txt
index 45091fc..a1c8688 100644
--- a/upatch-diff/CMakeLists.txt
+++ b/upatch-diff/CMakeLists.txt
@@ -18,8 +18,8 @@ install(
TARGETS
upatch-diff
PERMISSIONS
- OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
DESTINATION
${SYSCARE_LIBEXEC_DIR}
diff --git a/upatch-helper/helper/CMakeLists.txt b/upatch-helper/helper/CMakeLists.txt
index fefcebe..700722b 100644
--- a/upatch-helper/helper/CMakeLists.txt
+++ b/upatch-helper/helper/CMakeLists.txt
@@ -27,8 +27,8 @@ install(
${CMAKE_CURRENT_BINARY_DIR}/cc-helper
${CMAKE_CURRENT_BINARY_DIR}/c++-helper
PERMISSIONS
- OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
DESTINATION
${SYSCARE_LIBEXEC_DIR}
diff --git a/upatch-manage/CMakeLists.txt b/upatch-manage/CMakeLists.txt
index 850a308..e09aa9c 100644
--- a/upatch-manage/CMakeLists.txt
+++ b/upatch-manage/CMakeLists.txt
@@ -25,9 +25,8 @@ install(
TARGETS
${UPATCH_MANAGE}
PERMISSIONS
- OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ
- WORLD_READ WORLD_EXECUTE
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
DESTINATION
${SYSCARE_LIBEXEC_DIR}
)
--
2.34.1

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
From 6c1d025b3328845377338d6a09b30a23611ba934 Mon Sep 17 00:00:00 2001
From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
Date: Mon, 17 Jun 2024 16:18:20 +0800
Subject: [PATCH] syscare-abi: remove display limit of patch_info
When executing with `syscare info xxx`, show all the patches
it contains.
Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
---
syscare-abi/src/patch_info.rs | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
diff --git a/syscare-abi/src/patch_info.rs b/syscare-abi/src/patch_info.rs
index 246f830..65b7650 100644
--- a/syscare-abi/src/patch_info.rs
+++ b/syscare-abi/src/patch_info.rs
@@ -71,8 +71,6 @@ impl PatchInfo {
impl std::fmt::Display for PatchInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- const LIST_DISPLAY_LIMIT: usize = 9;
-
writeln!(f, "name: {}", self.name)?;
writeln!(f, "version: {}", self.version)?;
writeln!(f, "release: {}", self.release)?;
@@ -84,10 +82,6 @@ impl std::fmt::Display for PatchInfo {
if !self.entities.is_empty() {
writeln!(f, "entities:")?;
for (entity_idx, entity) in self.entities.iter().enumerate() {
- if entity_idx >= LIST_DISPLAY_LIMIT {
- writeln!(f, "* ......")?;
- break;
- }
writeln!(f, "* {}", entity.patch_name.to_string_lossy())?;
}
}
@@ -96,18 +90,9 @@ impl std::fmt::Display for PatchInfo {
writeln!(f, "patches:")?;
let last_idx = self.patches.len() - 1;
for (patch_idx, patch_file) in self.patches.iter().enumerate() {
- if patch_idx != last_idx {
- if patch_idx >= LIST_DISPLAY_LIMIT {
- writeln!(f, "* ......")?;
- break;
- }
- writeln!(f, "* {}", patch_file.name.to_string_lossy())?
- } else {
- if patch_idx >= LIST_DISPLAY_LIMIT {
- write!(f, "* ......")?;
- break;
- }
- write!(f, "* {}", patch_file.name.to_string_lossy())?
+ match patch_idx == last_idx {
+ false => writeln!(f, "* {}", patch_file.name.to_string_lossy())?,
+ true => write!(f, "* {}", patch_file.name.to_string_lossy())?,
}
}
}
--
2.34.1

View File

@ -1,49 +0,0 @@
From 345ea586c7fa196f0778eb28b78c9ceb51e5db75 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Sat, 29 Jun 2024 17:03:30 +0800
Subject: [PATCH] syscare-abi: fix clippy warnings
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-abi/src/patch_info.rs | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/syscare-abi/src/patch_info.rs b/syscare-abi/src/patch_info.rs
index 65b7650..f23ce9b 100644
--- a/syscare-abi/src/patch_info.rs
+++ b/syscare-abi/src/patch_info.rs
@@ -79,21 +79,17 @@ impl std::fmt::Display for PatchInfo {
writeln!(f, "target: {}", self.target.short_name())?;
writeln!(f, "license: {}", self.target.license)?;
writeln!(f, "description: {}", self.description)?;
- if !self.entities.is_empty() {
- writeln!(f, "entities:")?;
- for (entity_idx, entity) in self.entities.iter().enumerate() {
- writeln!(f, "* {}", entity.patch_name.to_string_lossy())?;
- }
+ writeln!(f, "entities:")?;
+ for entity in &self.entities {
+ writeln!(f, "* {}", entity.patch_name.to_string_lossy())?;
}
-
- if !self.patches.is_empty() {
- writeln!(f, "patches:")?;
- let last_idx = self.patches.len() - 1;
- for (patch_idx, patch_file) in self.patches.iter().enumerate() {
- match patch_idx == last_idx {
- false => writeln!(f, "* {}", patch_file.name.to_string_lossy())?,
- true => write!(f, "* {}", patch_file.name.to_string_lossy())?,
- }
+ writeln!(f, "patches:")?;
+ let last_idx = self.patches.len() - 1;
+ for (idx, patch) in self.patches.iter().enumerate() {
+ if idx == last_idx {
+ write!(f, "* {}", patch.name.to_string_lossy())?
+ } else {
+ writeln!(f, "* {}", patch.name.to_string_lossy())?
}
}
--
2.34.1

View File

@ -1,30 +0,0 @@
From 8f1372be9df4a60c6b3b50bfbfa6327fc2281647 Mon Sep 17 00:00:00 2001
From: lixiang_yewu <lixiang_yewu@cmss.chinamobile.com>
Date: Thu, 1 Aug 2024 02:34:16 +0000
Subject: [PATCH] =?UTF-8?q?update=20README.md.=20=E6=8C=87=E4=BB=A4?=
=?UTF-8?q?=E5=86=99=E9=94=99=E4=BA=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: lixiang_yewu <lixiang_yewu@cmss.chinamobile.com>
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 138c059..f12b03d 100644
--- a/README.md
+++ b/README.md
@@ -113,7 +113,7 @@ $ sudo syscare active redis-6.2.5-1/HP001
3. 补丁去激活
```bash
-$ sudo syscarae deactive redis-6.2.5-1/HP001
+$ sudo syscare deactive redis-6.2.5-1/HP001
```
4. 补丁卸载/移除
--
2.34.1

View File

@ -1,46 +0,0 @@
From f0c9f95fec6b8c3b6ee7f4852605b346d903c0e6 Mon Sep 17 00:00:00 2001
From: ningyu <405888464@qq.com>
Date: Fri, 9 Aug 2024 12:17:18 +0800
Subject: [PATCH] upatch-diff: fix .rela.text section status bug
Signed-off-by: ningyu <405888464@qq.com>
---
upatch-diff/create-diff-object.c | 2 +-
upatch-diff/elf-compare.c | 6 ++----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/upatch-diff/create-diff-object.c b/upatch-diff/create-diff-object.c
index 8830956..0eea362 100644
--- a/upatch-diff/create-diff-object.c
+++ b/upatch-diff/create-diff-object.c
@@ -868,7 +868,7 @@ static void verify_patchability(struct upatch_elf *uelf)
int errs = 0;
list_for_each_entry(sec, &uelf->sections, list) {
- if (sec->status == CHANGED && !sec->include) {
+ if (sec->status == CHANGED && !sec->include && !is_rela_section(sec)) {
log_normal("Section '%s' is changed, but it is not selected for inclusion\n", sec->name);
errs++;
}
diff --git a/upatch-diff/elf-compare.c b/upatch-diff/elf-compare.c
index 851c25f..5d39825 100644
--- a/upatch-diff/elf-compare.c
+++ b/upatch-diff/elf-compare.c
@@ -345,12 +345,10 @@ static inline void update_section_status(struct section *sec, enum status status
sec->twin->status = status;
}
if (is_rela_section(sec)) {
- if ((sec->base != NULL) &&
- (sec->base->sym != NULL)) {
+ if ((sec->base != NULL) && (sec->base->sym != NULL) && status != SAME) {
sec->base->sym->status = status;
}
- }
- else {
+ } else {
if (sec->sym != NULL) {
sec->sym->status = status;
}
--
2.34.1

View File

@ -1,34 +0,0 @@
From c5422f8da6735efb5746c167fef01d9c20bd69e5 Mon Sep 17 00:00:00 2001
From: ningyu <405888464@qq.com>
Date: Fri, 9 Aug 2024 14:18:50 +0800
Subject: [PATCH] upatch-manage: resolve plt firstly
Signed-off-by: ningyu <405888464@qq.com>
---
upatch-manage/upatch-resolve.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/upatch-manage/upatch-resolve.c b/upatch-manage/upatch-resolve.c
index 197ea2f..5f1c2de 100644
--- a/upatch-manage/upatch-resolve.c
+++ b/upatch-manage/upatch-resolve.c
@@ -254,12 +254,12 @@ static unsigned long resolve_symbol(struct upatch_elf *uelf,
* Approach 3 is more general, but difficulty to implement.
*/
- /* resolve from got */
- elf_addr = resolve_rela_dyn(uelf, obj, name, &patch_sym);
+ /* resolve from plt */
+ elf_addr = resolve_rela_plt(uelf, obj, name, &patch_sym);
- /* resolve from plt */
+ /* resolve from got */
if (!elf_addr) {
- elf_addr = resolve_rela_plt(uelf, obj, name, &patch_sym);
+ elf_addr = resolve_rela_dyn(uelf, obj, name, &patch_sym);
}
/* resolve from dynsym */
--
2.34.1

View File

@ -1,261 +0,0 @@
From d0bd28247e41b9cec11d61f0d1b6a86f78a4dabd Mon Sep 17 00:00:00 2001
From: ningyu <405888464@qq.com>
Date: Fri, 9 Aug 2024 14:33:01 +0800
Subject: [PATCH] upatch-manage: fix find upatch region bug
Signed-off-by: ningyu <405888464@qq.com>
---
upatch-manage/arch/aarch64/process.h | 28 ---------
upatch-manage/arch/x86_64/process.h | 28 ---------
upatch-manage/upatch-patch.c | 2 +-
upatch-manage/upatch-process.c | 91 ++++++----------------------
upatch-manage/upatch-process.h | 6 +-
5 files changed, 23 insertions(+), 132 deletions(-)
delete mode 100644 upatch-manage/arch/aarch64/process.h
delete mode 100644 upatch-manage/arch/x86_64/process.h
diff --git a/upatch-manage/arch/aarch64/process.h b/upatch-manage/arch/aarch64/process.h
deleted file mode 100644
index 8acf04b..0000000
--- a/upatch-manage/arch/aarch64/process.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * upatch-manage
- * Copyright (C) 2024 Huawei Technologies Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __PROCESS__
-#define __PROCESS__
-
-#ifndef MAX_DISTANCE
-#define MAX_DISTANCE 0x8000000
-#endif
-
-#endif
\ No newline at end of file
diff --git a/upatch-manage/arch/x86_64/process.h b/upatch-manage/arch/x86_64/process.h
deleted file mode 100644
index 5de8fc3..0000000
--- a/upatch-manage/arch/x86_64/process.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * upatch-manage
- * Copyright (C) 2024 Huawei Technologies Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __PROCESS__
-#define __PROCESS__
-
-#ifndef MAX_DISTANCE
-#define MAX_DISTANCE 0x80000000
-#endif
-
-#endif
\ No newline at end of file
diff --git a/upatch-manage/upatch-patch.c b/upatch-manage/upatch-patch.c
index 8a1ad41..c9fcbc9 100644
--- a/upatch-manage/upatch-patch.c
+++ b/upatch-manage/upatch-patch.c
@@ -271,7 +271,7 @@ static void *upatch_alloc(struct object_file *obj, size_t sz)
unsigned long addr;
struct vm_hole *hole = NULL;
- addr = object_find_patch_region_nolimit(obj, sz, &hole);
+ addr = object_find_patch_region(obj, sz, &hole);
if (!addr)
return NULL;
diff --git a/upatch-manage/upatch-process.c b/upatch-manage/upatch-process.c
index 84ec030..f4033cb 100644
--- a/upatch-manage/upatch-process.c
+++ b/upatch-manage/upatch-process.c
@@ -33,7 +33,6 @@
#include "list.h"
#include "log.h"
-#include "process.h"
#include "upatch-common.h"
#include "upatch-elf.h"
#include "upatch-process.h"
@@ -804,8 +803,9 @@ int vm_hole_split(struct vm_hole *hole, unsigned long alloc_start,
* and the next hole as a right candidate. Pace through them until there is
* enough space in the hole for the patch.
*
- * Since holes can be much larger than 2GiB take extra caution to allocate
- * patch region inside the (-2GiB, +2GiB) range from the original object.
+ * Due to relocation constraints, the hole position should be whin 4GB range
+ * from the obj.
+ * eg: R_AARCH64_ADR_GOT_PAGE
*/
unsigned long object_find_patch_region(struct object_file *obj, size_t memsize,
struct vm_hole **hole)
@@ -813,96 +813,41 @@ unsigned long object_find_patch_region(struct object_file *obj, size_t memsize,
struct list_head *head = &obj->proc->vmaholes;
struct vm_hole *left_hole = obj->previous_hole;
struct vm_hole *right_hole = next_hole(left_hole, head);
- unsigned long max_distance = MAX_DISTANCE;
+ unsigned long region_start = 0;
struct obj_vm_area *sovma;
-
unsigned long obj_start, obj_end;
- unsigned long region_start = 0, region_end = 0;
-
- log_debug("Looking for patch region for '%s'...\n", obj->name);
sovma = list_first_entry(&obj->vma, struct obj_vm_area, list);
obj_start = sovma->inmem.start;
sovma = list_entry(obj->vma.prev, struct obj_vm_area, list);
obj_end = sovma->inmem.end;
- max_distance -= memsize;
-
- /* TODO carefully check for the holes laying between obj_start and
- * obj_end, i.e. just after the executable segment of an executable
- */
- while (left_hole != NULL && right_hole != NULL) {
- if (right_hole != NULL &&
- right_hole->start - obj_start > max_distance)
- right_hole = NULL;
- else if (hole_size(right_hole) > memsize) {
- region_start = right_hole->start;
- region_end = (right_hole->end - obj_start) <=
- max_distance ?
- right_hole->end - memsize :
- obj_start + max_distance;
- *hole = right_hole;
- break;
- } else
- right_hole = next_hole(right_hole, head);
-
- if (left_hole != NULL &&
- obj_end - left_hole->end > max_distance)
- left_hole = NULL;
- else if (hole_size(left_hole) > memsize) {
- region_start = (obj_end - left_hole->start) <=
- max_distance ?
- left_hole->start :
- obj_end > max_distance ?
- obj_end - max_distance :
- 0;
- region_end = left_hole->end - memsize;
- *hole = left_hole;
- break;
- } else
- left_hole = prev_hole(left_hole, head);
- }
-
- if (region_start == region_end) {
- log_error("Cannot find suitable region for patch '%s'\n", obj->name);
- return -1UL;
- }
-
- region_start = (region_start >> (unsigned long)PAGE_SHIFT) << (unsigned long)PAGE_SHIFT;
- log_debug("Found patch region for '%s' at 0x%lx\n", obj->name,
- region_start);
-
- return region_start;
-}
-unsigned long object_find_patch_region_nolimit(struct object_file *obj, size_t memsize,
- struct vm_hole **hole)
-{
- struct list_head *head = &obj->proc->vmaholes;
- struct vm_hole *left_hole = obj->previous_hole;
- struct vm_hole *right_hole = next_hole(left_hole, head);
- unsigned long region_start = 0;
-
log_debug("Looking for patch region for '%s'...\n", obj->name);
- while (right_hole != NULL) {
+ while (right_hole != NULL || left_hole != NULL) {
if (hole_size(right_hole) > memsize) {
*hole = right_hole;
+ region_start = right_hole->start;
+ if (region_start + memsize - obj_start > MAX_DISTANCE) {
+ continue;
+ }
goto found;
- } else
- right_hole = next_hole(right_hole, head);
-
- while (left_hole != NULL)
+ }
if (hole_size(left_hole) > memsize) {
*hole = left_hole;
+ region_start = left_hole->end - memsize;
+ if (obj_end - region_start > MAX_DISTANCE) {
+ continue;
+ }
goto found;
- } else
- left_hole = prev_hole(left_hole, head);
+ }
+ right_hole = next_hole(right_hole, head);
+ left_hole = prev_hole(left_hole, head);
}
-
log_error("Cannot find suitable region for patch '%s'\n", obj->name);
return -1UL;
found:
- region_start = ((*hole)->start >> PAGE_SHIFT) << PAGE_SHIFT;
+ region_start = (region_start >> PAGE_SHIFT) << PAGE_SHIFT;
log_debug("Found patch region for '%s' 0xat %lx\n", obj->name,
region_start);
diff --git a/upatch-manage/upatch-process.h b/upatch-manage/upatch-process.h
index be44cb5..fdbd752 100644
--- a/upatch-manage/upatch-process.h
+++ b/upatch-manage/upatch-process.h
@@ -33,6 +33,10 @@
#define ELFMAG "\177ELF"
#define SELFMAG 4
+#ifndef MAX_DISTANCE
+#define MAX_DISTANCE (1UL << 32)
+#endif
+
enum {
MEM_READ,
MEM_WRITE,
@@ -143,7 +147,5 @@ int vm_hole_split(struct vm_hole *, unsigned long, unsigned long);
unsigned long object_find_patch_region(struct object_file *, size_t,
struct vm_hole **);
-unsigned long object_find_patch_region_nolimit(struct object_file *, size_t,
- struct vm_hole **);
#endif
--
2.34.1

View File

@ -1,26 +0,0 @@
From 7de47352a1201c4836ee71d119e07a5e544a16b4 Mon Sep 17 00:00:00 2001
From: Caohongtao <caohongtao_yewu@cmss.chinamobile.com>
Date: Wed, 14 Aug 2024 06:39:31 +0000
Subject: [PATCH] update README.md.
Signed-off-by: Caohongtao <caohongtao_yewu@cmss.chinamobile.com>
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f12b03d..15d4d48 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
## 软件架构
- 可以利用系统组件源代码与相应的patch问题制作出相应组件补丁的RPM包含补丁文件、依赖信息与配置信息等. 制作的补丁RPM可以上传到相应的补丁仓库中集群的系统demon定时去查询补丁仓库, 对系统中运行的CVE与软件错误进行热修复保证系统安全、稳定、高效运行。
+ 可以利用系统组件源代码与相应的patch问题制作出相应组件补丁的RPM包含补丁文件、依赖信息与配置信息等. 制作的补丁RPM可以上传到相应的补丁仓库中集群的系统daemon定时去查询补丁仓库, 对系统中运行的CVE与软件错误进行热修复保证系统安全、稳定、高效运行。
--
2.34.1

View File

@ -1,28 +0,0 @@
From e07e30d88d38227f9899b1a7a2e6de85e2f36c4e Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 13 Aug 2024 17:31:50 +0800
Subject: [PATCH] common: fix 'normalize empty path return current path' issue
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-common/src/fs/fs_impl.rs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/syscare-common/src/fs/fs_impl.rs b/syscare-common/src/fs/fs_impl.rs
index e794c98..29c5d6e 100644
--- a/syscare-common/src/fs/fs_impl.rs
+++ b/syscare-common/src/fs/fs_impl.rs
@@ -290,6 +290,10 @@ pub fn normalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
let mut new_path = PathBuf::new();
let orig_path = path.as_ref();
+ if orig_path.as_os_str().is_empty() {
+ return Ok(new_path);
+ }
+
if orig_path.is_relative() {
new_path.push(env::current_dir()?);
}
--
2.34.1

View File

@ -1,30 +0,0 @@
From 1c70edca6667730867cdd1e5691885ebae9c04bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=81=E5=AE=87?= <405888464@qq.com>
Date: Thu, 15 Aug 2024 07:33:24 +0000
Subject: [PATCH] syscared: Add PACTCH_CHECK action when status change from
Deactived to Actived
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: 宁宇 <405888464@qq.com>
---
syscared/src/patch/manager.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/syscared/src/patch/manager.rs b/syscared/src/patch/manager.rs
index d156e4a..3a724db 100644
--- a/syscared/src/patch/manager.rs
+++ b/syscared/src/patch/manager.rs
@@ -54,7 +54,7 @@ lazy_static! {
(PatchStatus::NotApplied, PatchStatus::Actived) => vec![PATCH_CHECK, PATCH_APPLY, PATCH_ACTIVE],
(PatchStatus::NotApplied, PatchStatus::Accepted) => vec![PATCH_CHECK, PATCH_APPLY, PATCH_ACTIVE, PATCH_ACCEPT],
(PatchStatus::Deactived, PatchStatus::NotApplied) => vec![PATCH_REMOVE],
- (PatchStatus::Deactived, PatchStatus::Actived) => vec![PATCH_ACTIVE],
+ (PatchStatus::Deactived, PatchStatus::Actived) => vec![PATCH_CHECK, PATCH_ACTIVE],
(PatchStatus::Deactived, PatchStatus::Accepted) => vec![PATCH_ACTIVE, PATCH_ACCEPT],
(PatchStatus::Actived, PatchStatus::NotApplied) => vec![PATCH_DEACTIVE, PATCH_REMOVE],
(PatchStatus::Actived, PatchStatus::Deactived) => vec![PATCH_DEACTIVE],
--
2.34.1

View File

@ -1,207 +0,0 @@
From 058670c8782b8b840fb99ddc174e00feb3b9ff89 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 16 Aug 2024 14:21:00 +0800
Subject: [PATCH] all: fix compile failure of rustc 1.80
Signed-off-by: renoseven <dev@renoseven.net>
---
syscare-build/src/build_root/package_root.rs | 6 ++----
syscare-build/src/build_root/patch_root.rs | 11 +++--------
syscared/src/patch/entity/kpatch.rs | 3 +--
syscared/src/patch/entity/upatch.rs | 3 +--
syscared/src/patch/resolver/kpatch.rs | 11 +++++++----
syscared/src/patch/resolver/upatch.rs | 7 +++----
6 files changed, 17 insertions(+), 24 deletions(-)
diff --git a/syscare-build/src/build_root/package_root.rs b/syscare-build/src/build_root/package_root.rs
index 75ff65d..eaac349 100644
--- a/syscare-build/src/build_root/package_root.rs
+++ b/syscare-build/src/build_root/package_root.rs
@@ -25,7 +25,6 @@ const BUILD_ROOT_DIR_NAME: &str = "patch";
#[derive(Debug, Clone)]
pub struct PackageRoot {
- pub path: PathBuf,
pub source: PathBuf,
pub debuginfo: PathBuf,
pub build_root: PackageBuildRoot,
@@ -33,17 +32,16 @@ pub struct PackageRoot {
impl PackageRoot {
pub fn new<P: AsRef<Path>>(directory: P) -> Result<Self> {
- let path = directory.as_ref().to_path_buf();
+ let path = directory.as_ref();
let source = path.join(SOURCE_DIR_NAME);
let debuginfo = path.join(DEBUGINFO_DIR_NAME);
let build_root = PackageBuildRoot::new(path.join(BUILD_ROOT_DIR_NAME))?;
- fs::create_dir_all(&path)?;
+ fs::create_dir_all(path)?;
fs::create_dir_all(&source)?;
fs::create_dir_all(&debuginfo)?;
Ok(Self {
- path,
source,
debuginfo,
build_root,
diff --git a/syscare-build/src/build_root/patch_root.rs b/syscare-build/src/build_root/patch_root.rs
index d493233..0aa0a1c 100644
--- a/syscare-build/src/build_root/patch_root.rs
+++ b/syscare-build/src/build_root/patch_root.rs
@@ -22,25 +22,20 @@ const OUTPUT_DIR_NAME: &str = "output";
#[derive(Debug, Clone)]
pub struct PatchRoot {
- pub path: PathBuf,
pub build: PathBuf,
pub output: PathBuf,
}
impl PatchRoot {
pub fn new<P: AsRef<Path>>(directory: P) -> Result<Self> {
- let path = directory.as_ref().to_path_buf();
+ let path = directory.as_ref();
let build = path.join(BUILD_DIR_NAME);
let output = path.join(OUTPUT_DIR_NAME);
- fs::create_dir_all(&path)?;
+ fs::create_dir_all(path)?;
fs::create_dir_all(&build)?;
fs::create_dir_all(&output)?;
- Ok(Self {
- path,
- build,
- output,
- })
+ Ok(Self { build, output })
}
}
diff --git a/syscared/src/patch/entity/kpatch.rs b/syscared/src/patch/entity/kpatch.rs
index ab2c8b2..a6b48c5 100644
--- a/syscared/src/patch/entity/kpatch.rs
+++ b/syscared/src/patch/entity/kpatch.rs
@@ -14,7 +14,7 @@
use std::{ffi::OsString, path::PathBuf, sync::Arc};
-use syscare_abi::{PatchInfo, PatchType};
+use syscare_abi::PatchInfo;
use uuid::Uuid;
/// Kernel patch function definition
@@ -61,7 +61,6 @@ impl std::fmt::Display for KernelPatchFunction {
pub struct KernelPatch {
pub uuid: Uuid,
pub name: OsString,
- pub kind: PatchType,
pub info: Arc<PatchInfo>,
pub pkg_name: String,
pub module_name: OsString,
diff --git a/syscared/src/patch/entity/upatch.rs b/syscared/src/patch/entity/upatch.rs
index ef24866..0fbacb4 100644
--- a/syscared/src/patch/entity/upatch.rs
+++ b/syscared/src/patch/entity/upatch.rs
@@ -14,7 +14,7 @@
use std::{ffi::OsString, path::PathBuf, sync::Arc};
-use syscare_abi::{PatchInfo, PatchType};
+use syscare_abi::PatchInfo;
use uuid::Uuid;
/// User patch function definition
@@ -58,7 +58,6 @@ impl std::fmt::Display for UserPatchFunction {
pub struct UserPatch {
pub uuid: Uuid,
pub name: OsString,
- pub kind: PatchType,
pub info: Arc<PatchInfo>,
pub pkg_name: String,
pub functions: Vec<UserPatchFunction>,
diff --git a/syscared/src/patch/resolver/kpatch.rs b/syscared/src/patch/resolver/kpatch.rs
index 7946c42..85ec18e 100644
--- a/syscared/src/patch/resolver/kpatch.rs
+++ b/syscared/src/patch/resolver/kpatch.rs
@@ -21,7 +21,7 @@ use std::{
use anyhow::{anyhow, Context, Result};
use object::{NativeFile, Object, ObjectSection};
-use syscare_abi::{PatchEntity, PatchInfo, PatchType};
+use syscare_abi::{PatchEntity, PatchInfo};
use syscare_common::{
concat_os,
ffi::{CStrExt, OsStrExt},
@@ -71,7 +71,7 @@ mod ffi {
unsafe impl Pod for KpatchFunction {}
pub struct KpatchRelocation {
- pub addr: (u64, Relocation),
+ pub _addr: (u64, Relocation),
pub name: (u64, Relocation),
pub object: (u64, Relocation),
}
@@ -93,7 +93,11 @@ mod ffi {
if let (Some(addr), Some(name), Some(object)) =
(self.0.next(), self.0.next(), self.0.next())
{
- return Some(KpatchRelocation { addr, name, object });
+ return Some(KpatchRelocation {
+ _addr: addr,
+ name,
+ object,
+ });
}
None
}
@@ -205,7 +209,6 @@ impl PatchResolverImpl for KpatchResolverImpl {
"/",
&patch_entity.patch_target
),
- kind: PatchType::KernelPatch,
info: patch_info.clone(),
pkg_name: patch_info.target.full_name(),
module_name,
diff --git a/syscared/src/patch/resolver/upatch.rs b/syscared/src/patch/resolver/upatch.rs
index cb06c24..e8c2f2c 100644
--- a/syscared/src/patch/resolver/upatch.rs
+++ b/syscared/src/patch/resolver/upatch.rs
@@ -21,7 +21,7 @@ use std::{
use anyhow::{anyhow, Context, Result};
use object::{NativeFile, Object, ObjectSection};
-use syscare_abi::{PatchEntity, PatchInfo, PatchType};
+use syscare_abi::{PatchEntity, PatchInfo};
use syscare_common::{concat_os, ffi::CStrExt, fs};
use super::PatchResolverImpl;
@@ -59,7 +59,7 @@ mod ffi {
pub const UPATCH_FUNCTION_OFFSET: usize = 40;
pub struct UpatchRelocation {
- pub addr: (u64, Relocation),
+ pub _addr: (u64, Relocation),
pub name: (u64, Relocation),
}
@@ -78,7 +78,7 @@ mod ffi {
fn next(&mut self) -> Option<Self::Item> {
if let (Some(addr), Some(name)) = (self.0.next(), self.0.next()) {
- return Some(UpatchRelocation { addr, name });
+ return Some(UpatchRelocation { _addr: addr, name });
}
None
}
@@ -168,7 +168,6 @@ impl PatchResolverImpl for UpatchResolverImpl {
"/",
fs::file_name(&patch_entity.patch_target)
),
- kind: PatchType::UserPatch,
info: patch_info.clone(),
pkg_name: patch_info.target.full_name(),
patch_file: patch_root.join(&patch_entity.patch_name),
--
2.34.1

View File

@ -1,70 +1,19 @@
%define build_version %{version}-%{release}
%define kernel_devel_rpm %(echo $(rpm -q kernel-devel | head -n 1))
%define kernel_name %(echo $(rpm -q --qf "\%%{VERSION}-\%%{RELEASE}.\%%{ARCH}" %{kernel_devel_rpm}))
%define build_version %{version}-%{release}
############################################
############ Package syscare ###############
############################################
Name: syscare
Version: 1.2.1
Release: 10
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-syscared-fix-cannot-find-process-of-dynlib-patch-iss.patch
Patch0005: 0005-syscared-optimize-patch-error-logic.patch
Patch0006: 0006-syscared-optimize-transaction-creation-logic.patch
Patch0007: 0007-upatch-manage-optimize-output.patch
Patch0008: 0008-common-impl-CStr-from_bytes_with_next_nul.patch
Patch0009: 0009-syscared-improve-patch-management.patch
Patch0010: 0010-syscared-stop-activating-ignored-process-on-new-proc.patch
Patch0011: 0011-syscared-adapt-upatch-manage-exit-code-change.patch
Patch0012: 0012-upatch-manage-change-exit-code.patch
Patch0013: 0013-upatch-manage-change-the-way-to-calculate-frozen-tim.patch
Patch0014: 0014-abi-change-uuid-string-to-uuid-bytes.patch
Patch0015: 0015-upatch-build-fix-file-detection-cause-build-failure-.patch
Patch0016: 0016-upatch-diff-optimize-log-output.patch
Patch0017: 0017-security-change-directory-permission.patch
Patch0018: 0018-security-change-daemon-socket-permission.patch
Patch0019: 0019-upatch-manage-Fixed-the-core-dump-issue-after-applyi.patch
Patch0020: 0020-upatch-diff-fix-lookup_relf-failed-issue.patch
Patch0021: 0021-upatch-diff-only-check-changed-file-symbols.patch
Patch0022: 0022-upatch-diff-remove-rela-check-while-build-rebuilding.patch
Patch0023: 0023-syscared-fix-apply-kernel-module-patch-failure-issue.patch
Patch0024: 0024-syscare-build-fix-build-oot-module-failure-issue.patch
Patch0025: 0025-all-finding-executable-from-environment-variables.patch
Patch0026: 0026-all-remove-redundant-code.patch
Patch0027: 0027-abi-reexport-uuid.patch
Patch0028: 0028-all-add-c-rust-compilation-options.patch
Patch0029: 0029-common-fix-failed-to-set-selinux-status-issue.patch
Patch0030: 0030-upatch-diff-exit-with-error-when-any-tls-var-include.patch
Patch0031: 0031-upatch-diff-fix-lookup_relf-duplicate-failure.patch
Patch0032: 0032-upatch-diff-fix-memory-leak.patch
Patch0033: 0033-upatch-hijacker-fix-memory-leak.patch
Patch0034: 0034-upatch-manage-fix-memory-leak.patch
Patch0035: 0035-security-sanitize-sensitive-code.patch
Patch0036: 0036-all-implement-asan-gcov-build-type.patch
Patch0037: 0037-all-clean-code.patch
Patch0038: 0038-syscare-abi-remove-display-limit-of-patch_info.patch
Patch0039: 0039-syscare-abi-fix-clippy-warnings.patch
Patch0040: 0040-update-README.md.patch
Patch0041: 0041-upatch-diff-fix-.rela.text-section-status-bug.patch
Patch0042: 0042-upatch-manage-resolve-plt-firstly.patch
Patch0043: 0043-upatch-manage-fix-find-upatch-region-bug.patch
Patch0044: 0044-update-README.md.patch
Patch0045: 0045-common-fix-normalize-empty-path-return-current-path-.patch
Patch0046: 0046-syscared-Add-PACTCH_CHECK-action-when-status-change-.patch
Patch0047: 0047-all-fix-compile-failure-of-rustc-1.80.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
@ -85,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
@ -140,8 +90,8 @@ fi
%dir /usr/libexec/syscare
%attr(0555,root,root) /usr/bin/syscare
%attr(0550,root,root) /usr/bin/syscared
%attr(0550,root,root) /usr/lib/systemd/system/syscare.service
%attr(0550,root,root) /usr/libexec/syscare/upatch-manage
%attr(0550,root,root) /usr/lib/systemd/system/syscare.service
############################################
########## Package syscare-build ###########
@ -159,218 +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,0555)
%dir /usr/libexec/syscare
%attr(550,root,root) /usr/bin/upatchd
%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/as-helper
%attr(555,root,root) /usr/libexec/syscare/cc-helper
%attr(555,root,root) /usr/libexec/syscare/c++-helper
%attr(555,root,root) /usr/libexec/syscare/gcc-helper
%attr(555,root,root) /usr/libexec/syscare/g++-helper
%attr(555,root,root) /usr/libexec/syscare/gnu-as-helper
%attr(555,root,root) /usr/libexec/syscare/gnu-compiler-helper
%attr(440,root,root) /usr/libexec/syscare/upatch_helper.ko
%attr(550,root,root) /usr/lib/systemd/system/upatch.service
%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
* Fri Aug 16 2024 renoseven<dev@renoseven.net> - 1.2.1-10
- upatch-diff: fix '.rela' '.rela.text' resolving issue
- upatch-manage: fix plt resolving issue
- upatch-manage: fix patch region finding issue
- common: fix normalizing empty path return non-empty issue
- syscared: add check action for [DEACTIVED -> ACTIVED] transition
- abi: remove display limit of patch info
- all: clean code
- all: implement asan gcov build type
- security: sanitize sensitive code
- upatch-manage: fix memory leak
- upatch-helper: fix memory leak
- upatch-diff: fix memory leak
- upatch-diff: fix find duplicate symbol issue
- upatch-diff: prevent tls variable modification
- common: fix failed to set selinux status issue
- all: add compile options
- all: remove redundant code
- all: finding executable from environment variables
* Wed Jul 03 2024 yueyuankun<yueyuankun@kylinos.cn> - 1.2.1-9
- add excludearch loongarch64
* Mon May 20 2024 ningyu<ningyu9@huawei.com> - 1.2.1-8
- syscared: fix apply kernel module patch failure issue
- syscare-build: fix build oot module failure issue
* Tue May 14 2024 ningyu<ningyu9@huawei.com> - 1.2.1-7
- upatch diff only check changed file symbols
- upatch diff remove rela check while build rebuilding
* Sat May 11 2024 renoseven<dev@renoseven.net> - 1.2.1-6
- upatch-diff: fix 'lookup_elf failed' issue
- upatch-manage: fixed the core dump issue after applying hot patches to nginx on x86_64 architecture
- security: change daemon socket permission
- security: change directory permission
- upatch-build: fix 'file detection cause build failure' issue
- syscared: stop activating ignored process on new process start
* 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