update to 1.2.1-6

Signed-off-by: renoseven <dev@renoseven.net>
This commit is contained in:
renoseven 2024-05-11 18:39:50 +08:00
parent 2fb8f6dcfe
commit 6f0c82e947
24 changed files with 2350 additions and 218 deletions

View File

@ -1,7 +1,7 @@
From 8c09e8b3d9d59012c1019c01ac2246c770501c75 Mon Sep 17 00:00:00 2001
From: ningyu <405888464@qq.com>
Date: Sun, 7 Apr 2024 10:50:13 +0800
Subject: [PATCH 01/17] upatch-hijacker: fix compile bug container_of_safe =>
Subject: [PATCH 01/20] upatch-hijacker: fix compile bug container_of_safe =>
container_of
---
@ -29,5 +29,5 @@ index a9c18ba..3049556 100644
\ No newline at end of file
+}
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From a535e14a7db49df3c8aab017e32b92d8e5bb4087 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 10 Apr 2024 10:25:21 +0800
Subject: [PATCH 02/17] daemon: fix 'cannot get file selinux xattr when selinux
Subject: [PATCH 02/20] daemon: fix 'cannot get file selinux xattr when selinux
is not enforcing' issue
Signed-off-by: renoseven <dev@renoseven.net>
@ -215,5 +215,5 @@ index 028a4c8..8ac12e7 100644
debug!("Initializing hijacker ioctl channel...");
let ioctl = HijackerIoctl::new(KMOD_DEV_PATH)?;
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From e5294afa8135f54f44196bd92e5a32c2b09b9bda Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 10 Apr 2024 12:19:51 +0800
Subject: [PATCH 03/17] syscared: fix 'syscare check command does not check
Subject: [PATCH 03/20] syscared: fix 'syscare check command does not check
symbol confiliction' issue
Signed-off-by: renoseven <dev@renoseven.net>
@ -381,5 +381,5 @@ index b353bdf..f633567 100644
}
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From 729f32db079e2aace7cf355d480627b0bbf37e8c Mon Sep 17 00:00:00 2001
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 06/17] syscared: fix 'cannot find process of dynlib patch'
Subject: [PATCH 04/20] syscared: fix 'cannot find process of dynlib patch'
issue
1. For detecting process mapped dynamic library,
@ -21,7 +21,7 @@ Signed-off-by: renoseven <dev@renoseven.net>
4 files changed, 270 insertions(+), 199 deletions(-)
diff --git a/syscared/src/patch/driver/upatch/mod.rs b/syscared/src/patch/driver/upatch/mod.rs
index 98b1e34..a7fa154 100644
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::{
@ -37,7 +37,7 @@ index 98b1e34..a7fa154 100644
use monitor::UserPatchMonitor;
use target::PatchTarget;
-type ActivePatchMap = Arc<Mutex<IndexMap<PathBuf, ActivePatch>>>;
-pub(self) type ActivePatchMap = Arc<Mutex<IndexMap<PathBuf, ActivePatch>>>;
+type ElfPatchMap = Arc<Mutex<IndexMap<PathBuf, ElfPatchRecord>>>;
#[derive(Default)]
@ -683,5 +683,5 @@ index bab2974..f0745f0 100644
Ok(())
--
2.41.0
2.34.1

View File

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

View File

@ -1,7 +1,7 @@
From 520e46ddd8f393125509a436134255765c5960cc Mon Sep 17 00:00:00 2001
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 07/17] syscared: optimize patch error logic
Subject: [PATCH 05/20] syscared: optimize patch error logic
Signed-off-by: renoseven <dev@renoseven.net>
---
@ -99,5 +99,5 @@ index f0745f0..1908520 100644
.exit_code();
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From 4ceb42b4a81cfb573aad4b4542f143be4c0ae90c Mon Sep 17 00:00:00 2001
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 08/17] syscared: optimize transaction creation logic
Subject: [PATCH 06/20] syscared: optimize transaction creation logic
Signed-off-by: renoseven <dev@renoseven.net>
---
@ -108,5 +108,5 @@ index 98494b1..b009d46 100644
})
}
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From 399de1f2021ae91ee6fc1271b1ee4f2f5933eaf1 Mon Sep 17 00:00:00 2001
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 09/17] upatch-manage: optimize output
Subject: [PATCH 07/20] upatch-manage: optimize output
Signed-off-by: renoseven <dev@renoseven.net>
---
@ -132,5 +132,5 @@ index 0d57238..cd3f7e0 100644
}
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From b64fa8df5ef916510e345cdd0382c32364d0c255 Mon Sep 17 00:00:00 2001
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 12/17] common: impl CStr::from_bytes_with_next_nul()
Subject: [PATCH 08/20] common: impl CStr::from_bytes_with_next_nul()
Signed-off-by: renoseven <dev@renoseven.net>
---
@ -43,5 +43,5 @@ index 060149a..4f3f26d 100644
#[test]
fn test_cstr() {
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From 13df37eba5f5b763922b7b2b91e4097e93b13158 Mon Sep 17 00:00:00 2001
From 354e0888188d4cabd9fff9912fa0935e4e1b4b52 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 16 Apr 2024 14:20:27 +0800
Subject: [PATCH 13/17] syscared: improve patch management
Subject: [PATCH 09/20] syscared: improve patch management
Signed-off-by: renoseven <dev@renoseven.net>
---
@ -19,8 +19,8 @@ Signed-off-by: renoseven <dev@renoseven.net>
syscared/src/patch/entity/symbol.rs | 10 +-
syscared/src/patch/entity/upatch.rs | 12 +-
syscared/src/patch/resolver/kpatch.rs | 141 +++---
syscared/src/patch/resolver/upatch.rs | 97 ++--
15 files changed, 832 insertions(+), 716 deletions(-)
syscared/src/patch/resolver/upatch.rs | 98 ++--
15 files changed, 833 insertions(+), 716 deletions(-)
create mode 100644 syscared/src/patch/driver/upatch/entity.rs
delete mode 100644 syscared/src/patch/driver/upatch/process.rs
@ -1935,7 +1935,7 @@ index 4e62431..ef24866 100644
pub target_elf: PathBuf,
pub checksum: String,
diff --git a/syscared/src/patch/resolver/kpatch.rs b/syscared/src/patch/resolver/kpatch.rs
index 50711eb..524482e 100644
index 7de81b3..8738225 100644
--- a/syscared/src/patch/resolver/kpatch.rs
+++ b/syscared/src/patch/resolver/kpatch.rs
@@ -13,8 +13,7 @@
@ -1946,10 +1946,10 @@ index 50711eb..524482e 100644
- os::unix::ffi::OsStringExt,
+ ffi::{CStr, OsString},
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
};
@@ -23,10 +22,14 @@ use anyhow::{anyhow, Context, Result};
use object::{NativeFile, Object, ObjectSection};
@@ -25,10 +24,14 @@ use object::{NativeFile, Object, ObjectSection};
use uuid::Uuid;
use syscare_abi::{PatchEntity, PatchInfo, PatchType};
-use syscare_common::{concat_os, ffi::OsStrExt, fs};
@ -1965,7 +1965,7 @@ index 50711eb..524482e 100644
const KPATCH_SUFFIX: &str = ".ko";
const KPATCH_SYS_DIR: &str = "/sys/kernel/livepatch";
@@ -35,7 +38,10 @@ const KPATCH_SYS_FILE_NAME: &str = "enabled";
@@ -37,7 +40,10 @@ const KPATCH_SYS_FILE_NAME: &str = "enabled";
mod ffi {
use std::os::raw::{c_char, c_long, c_ulong};
@ -1977,7 +1977,7 @@ index 50711eb..524482e 100644
#[repr(C)]
#[derive(Debug, Clone, Copy)]
@@ -52,9 +58,9 @@ mod ffi {
@@ -54,9 +60,9 @@ mod ffi {
pub ref_offset: c_long,
}
@ -1990,7 +1990,7 @@ index 50711eb..524482e 100644
/*
* SAFETY: This struct is
@@ -64,24 +70,34 @@ mod ffi {
@@ -66,24 +72,34 @@ mod ffi {
*/
unsafe impl Pod for KpatchFunction {}
@ -2038,7 +2038,7 @@ index 50711eb..524482e 100644
}
use ffi::*;
@@ -113,19 +129,19 @@ impl KpatchResolverImpl {
@@ -115,19 +131,19 @@ impl KpatchResolverImpl {
.with_context(|| format!("Failed to read section '{}'", KPATCH_FUNCS_SECTION))?;
// Resolve patch functions
@ -2064,7 +2064,7 @@ index 50711eb..524482e 100644
old_addr: function.old_addr,
old_size: function.old_size,
new_addr: function.new_addr,
@@ -134,44 +150,35 @@ impl KpatchResolverImpl {
@@ -136,44 +152,35 @@ impl KpatchResolverImpl {
}
// Relocate patch functions
@ -2138,7 +2138,7 @@ index 50711eb..524482e 100644
}
Ok(())
@@ -206,10 +213,10 @@ impl PatchResolverImpl for KpatchResolverImpl {
@@ -208,10 +215,10 @@ impl PatchResolverImpl for KpatchResolverImpl {
module_name,
patch_file,
sys_file,
@ -2152,22 +2152,24 @@ index 50711eb..524482e 100644
Ok(Patch::KernelPatch(patch))
}
diff --git a/syscared/src/patch/resolver/upatch.rs b/syscared/src/patch/resolver/upatch.rs
index 15c7363..5df11db 100644
index 507bf8e..985b8f1 100644
--- a/syscared/src/patch/resolver/upatch.rs
+++ b/syscared/src/patch/resolver/upatch.rs
@@ -12,21 +12,28 @@
@@ -12,22 +12,30 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::Path, sync::Arc};
-use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::Path, str::FromStr, sync::Arc};
+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, fs};
@ -2188,7 +2190,7 @@ index 15c7363..5df11db 100644
#[repr(C)]
#[derive(Debug, Clone, Copy)]
@@ -48,25 +55,34 @@ mod ffi {
@@ -49,25 +57,34 @@ mod ffi {
*/
unsafe impl Pod for UpatchFunction {}
@ -2236,7 +2238,7 @@ index 15c7363..5df11db 100644
}
use ffi::*;
@@ -98,17 +114,17 @@ impl UpatchResolverImpl {
@@ -99,17 +116,17 @@ impl UpatchResolverImpl {
.with_context(|| format!("Failed to read section '{}'", UPATCH_FUNCS_SECTION))?;
// Resolve patch functions
@ -2259,7 +2261,7 @@ index 15c7363..5df11db 100644
name: OsString::new(),
old_addr: function.old_addr,
old_size: function.old_size,
@@ -118,25 +134,20 @@ impl UpatchResolverImpl {
@@ -119,25 +136,20 @@ impl UpatchResolverImpl {
}
// Relocate patch functions
@ -2299,7 +2301,7 @@ index 15c7363..5df11db 100644
}
Ok(())
@@ -164,10 +175,10 @@ impl PatchResolverImpl for UpatchResolverImpl {
@@ -165,10 +177,10 @@ impl PatchResolverImpl for UpatchResolverImpl {
pkg_name: patch_info.target.full_name(),
patch_file: patch_root.join(&patch_entity.patch_name),
target_elf: patch_entity.patch_target.clone(),
@ -2313,5 +2315,5 @@ index 15c7363..5df11db 100644
Ok(Patch::UserPatch(patch))
}
--
2.41.0
2.34.1

View File

@ -1,35 +0,0 @@
From 51aa26c1eeb7514bceb0194b601de560c6b9d74a Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:35:57 +0800
Subject: [PATCH 10/17] syscared: optimize patch error logic
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/patch/driver/upatch/sys.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
index f0745f0..1908520 100644
--- a/syscared/src/patch/driver/upatch/sys.rs
+++ b/syscared/src/patch/driver/upatch/sys.rs
@@ -20,7 +20,7 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
.arg(target_elf)
.arg("--upatch")
.arg(patch_file)
- .stdout(Level::Debug)
+ .stdout(Level::Info)
.run_with_output()?
.exit_code();
@@ -44,7 +44,7 @@ pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Pat
.arg(target_elf)
.arg("--upatch")
.arg(patch_file)
- .stdout(Level::Debug)
+ .stdout(Level::Info)
.run_with_output()?
.exit_code();
--
2.41.0

View File

@ -1,7 +1,7 @@
From 3ee829f2156651f2284e072ba63abd196ee43294 Mon Sep 17 00:00:00 2001
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 14/17] syscared: stop activating ignored process on new
Subject: [PATCH 10/20] syscared: stop activating ignored process on new
process start
Signed-off-by: renoseven <dev@renoseven.net>
@ -233,5 +233,5 @@ index dd07e9b..66eecf5 100644
}
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From 96ccd901456d950761835befde8979519575778d Mon Sep 17 00:00:00 2001
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 15/17] syscared: adapt upatch-manage exit code change
Subject: [PATCH 11/20] syscared: adapt upatch-manage exit code change
1. upatch driver treats EEXIST as an error
@ -31,5 +31,5 @@ index bfeb1b8..a388bc6 100644
}
}
--
2.41.0
2.34.1

View File

@ -1,35 +0,0 @@
From 1d67bb57973cc0bc4b227c4359c15c4f31a1c82c Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 12 Apr 2024 11:40:25 +0800
Subject: [PATCH 11/17] syscared: optimize transaction creation logic
Signed-off-by: renoseven <dev@renoseven.net>
---
syscared/src/patch/driver/upatch/sys.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/syscared/src/patch/driver/upatch/sys.rs b/syscared/src/patch/driver/upatch/sys.rs
index 1908520..f0745f0 100644
--- a/syscared/src/patch/driver/upatch/sys.rs
+++ b/syscared/src/patch/driver/upatch/sys.rs
@@ -20,7 +20,7 @@ pub fn active_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Path)
.arg(target_elf)
.arg("--upatch")
.arg(patch_file)
- .stdout(Level::Info)
+ .stdout(Level::Debug)
.run_with_output()?
.exit_code();
@@ -44,7 +44,7 @@ pub fn deactive_patch(uuid: &Uuid, pid: i32, target_elf: &Path, patch_file: &Pat
.arg(target_elf)
.arg("--upatch")
.arg(patch_file)
- .stdout(Level::Info)
+ .stdout(Level::Debug)
.run_with_output()?
.exit_code();
--
2.41.0

View File

@ -1,7 +1,7 @@
From 10dc2c5843156d032277cc0a3a85e2e8df3a5146 Mon Sep 17 00:00:00 2001
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 16/17] upatch-manage: change exit code
Subject: [PATCH 12/20] upatch-manage: change exit code
1. return more specific exit code
2. change exit code from EEXIST to 0 when patching existing patch (uuid)
@ -442,5 +442,5 @@ index 39e8f59..1309a6e 100644
#include <string.h>
#include <unistd.h>
--
2.41.0
2.34.1

View File

@ -1,7 +1,7 @@
From ce0702b2da3820a3e872fd6563d5ce9e51cab130 Mon Sep 17 00:00:00 2001
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 17/17] upatch-manage: change the way to calculate frozen time
Subject: [PATCH 13/20] upatch-manage: change the way to calculate frozen time
Signed-off-by: renoseven <dev@renoseven.net>
---
@ -136,5 +136,5 @@ index 5a8f927..ab972ac 100644
}
--
2.41.0
2.34.1

View File

@ -1,8 +1,9 @@
From b53cb3d2903ea8ee3667f892b813648da7bc59a7 Mon Sep 17 00:00:00 2001
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 04/17] Change uuid type to Uuid
Subject: [PATCH 14/20] abi: change uuid string to uuid bytes
Signed-off-by: ningyu <ningyu9@huawei.com>
---
Cargo.lock | 1 +
syscare-abi/Cargo.toml | 1 +
@ -12,8 +13,8 @@ Subject: [PATCH 04/17] Change uuid type to Uuid
syscare-build/src/patch/metadata.rs | 4 +++-
syscare-build/src/patch/user_patch/upatch_builder.rs | 4 ++--
syscared/src/patch/resolver/kpatch.rs | 4 +---
syscared/src/patch/resolver/upatch.rs | 5 ++---
9 files changed, 19 insertions(+), 16 deletions(-)
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
@ -165,12 +166,12 @@ index ad8710b..1e0e6b6 100644
kind: ubuild_params.patch_type,
version: ubuild_params.patch_version.to_owned(),
diff --git a/syscared/src/patch/resolver/kpatch.rs b/syscared/src/patch/resolver/kpatch.rs
index 7de81b3..50711eb 100644
index 8738225..524482e 100644
--- a/syscared/src/patch/resolver/kpatch.rs
+++ b/syscared/src/patch/resolver/kpatch.rs
@@ -16,13 +16,11 @@ use std::{
ffi::OsString,
os::unix::ffi::OsStringExt,
@@ -15,13 +15,11 @@
use std::{
ffi::{CStr, OsString},
path::{Path, PathBuf},
- str::FromStr,
sync::Arc,
@ -181,8 +182,8 @@ index 7de81b3..50711eb 100644
-use uuid::Uuid;
use syscare_abi::{PatchEntity, PatchInfo, PatchType};
use syscare_common::{concat_os, ffi::OsStrExt, fs};
@@ -194,7 +192,7 @@ impl PatchResolverImpl for KpatchResolverImpl {
use syscare_common::{
@@ -201,7 +199,7 @@ impl PatchResolverImpl for KpatchResolverImpl {
.join(KPATCH_SYS_FILE_NAME);
let mut patch = KernelPatch {
@ -192,23 +193,24 @@ index 7de81b3..50711eb 100644
patch_info.target.short_name(),
"/",
diff --git a/syscared/src/patch/resolver/upatch.rs b/syscared/src/patch/resolver/upatch.rs
index 507bf8e..15c7363 100644
index 985b8f1..5df11db 100644
--- a/syscared/src/patch/resolver/upatch.rs
+++ b/syscared/src/patch/resolver/upatch.rs
@@ -12,11 +12,10 @@
* See the Mulan PSL v2 for more details.
*/
-use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::Path, str::FromStr, sync::Arc};
+use std::{ffi::OsString, os::unix::ffi::OsStringExt, path::Path, sync::Arc};
@@ -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, fs};
@@ -152,7 +151,7 @@ impl PatchResolverImpl for UpatchResolverImpl {
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 {
@ -218,5 +220,5 @@ index 507bf8e..15c7363 100644
patch_info.target.short_name(),
"/",
--
2.41.0
2.34.1

View File

@ -0,0 +1,557 @@
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 15/20] 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

@ -0,0 +1,469 @@
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 16/20] 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

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

@ -0,0 +1,826 @@
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 18/20] 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

@ -0,0 +1,132 @@
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 19/20] 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

@ -0,0 +1,144 @@
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 20/20] 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

@ -11,7 +11,7 @@
############################################
Name: syscare
Version: 1.2.1
Release: 5
Release: 6
Summary: System hot-fix service
License: MulanPSL-2.0 and GPL-2.0-only
URL: https://gitee.com/openeuler/syscare
@ -20,20 +20,23 @@ Source0: %{name}-%{version}.tar.gz
Patch0001: 0001-upatch-hijacker-fix-compile-bug.patch
Patch0002: 0002-daemon-fix-cannot-get-file-selinux-xattr-when-selinu.patch
Patch0003: 0003-syscared-fix-syscare-check-command-does-not-check-sy.patch
Patch0004: 0004-Change-uuid-type-to-Uuid.patch
Patch0005: 0005-fix-clippy-warning.patch
Patch0006: 0006-syscared-fix-cannot-find-process-of-dynlib-patch-iss.patch
Patch0007: 0007-syscared-optimize-patch-error-logic.patch
Patch0008: 0008-syscared-optimize-transaction-creation-logic.patch
Patch0009: 0009-upatch-manage-optimize-output.patch
Patch0010: 0010-syscared-optimize-patch-error-logic.patch
Patch0011: 0011-syscared-optimize-transaction-creation-logic.patch
Patch0012: 0012-common-impl-CStr-from_bytes_with_next_nul.patch
Patch0013: 0013-syscared-improve-patch-management.patch
Patch0014: 0014-syscared-stop-activating-ignored-process-on-new-proc.patch
Patch0015: 0015-syscared-adapt-upatch-manage-exit-code-change.patch
Patch0016: 0016-upatch-manage-change-exit-code.patch
Patch0017: 0017-upatch-manage-change-the-way-to-calculate-frozen-tim.patch
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
BuildRequires: cmake >= 3.14 make
BuildRequires: rust >= 1.51 cargo >= 1.51
@ -110,10 +113,10 @@ fi
%files
%defattr(-,root,root,-)
%dir /usr/libexec/syscare
%attr(644,root,root) /usr/lib/systemd/system/syscare.service
%attr(755,root,root) /usr/bin/syscared
%attr(755,root,root) /usr/bin/syscare
%attr(755,root,root) /usr/libexec/syscare/upatch-manage
%attr(550,root,root) /usr/lib/systemd/system/syscare.service
%attr(550,root,root) /usr/libexec/syscare/upatch-manage
%attr(550,root,root) /usr/bin/syscared
%attr(555,root,root) /usr/bin/syscare
############################################
########## Package syscare-build ###########
@ -167,24 +170,31 @@ fi
%files build
%defattr(-,root,root,-)
%dir /usr/libexec/syscare
%attr(644,root,root) /usr/lib/systemd/system/upatch.service
%attr(755,root,root) /usr/bin/upatchd
%attr(755,root,root) /usr/libexec/syscare/syscare-build
%attr(755,root,root) /usr/libexec/syscare/upatch-build
%attr(755,root,root) /usr/libexec/syscare/upatch-diff
%attr(755,root,root) /usr/libexec/syscare/as-hijacker
%attr(755,root,root) /usr/libexec/syscare/cc-hijacker
%attr(755,root,root) /usr/libexec/syscare/c++-hijacker
%attr(755,root,root) /usr/libexec/syscare/gcc-hijacker
%attr(755,root,root) /usr/libexec/syscare/g++-hijacker
%attr(755,root,root) /usr/libexec/syscare/gnu-as-hijacker
%attr(755,root,root) /usr/libexec/syscare/gnu-compiler-hijacker
%attr(755,root,root) /usr/libexec/syscare/upatch_hijacker.ko
%attr(550,root,root) /usr/lib/systemd/system/upatch.service
%attr(550,root,root) /usr/bin/upatchd
%attr(440,root,root) /usr/libexec/syscare/upatch_hijacker.ko
%attr(555,root,root) /usr/libexec/syscare/syscare-build
%attr(555,root,root) /usr/libexec/syscare/upatch-build
%attr(555,root,root) /usr/libexec/syscare/upatch-diff
%attr(555,root,root) /usr/libexec/syscare/as-hijacker
%attr(555,root,root) /usr/libexec/syscare/cc-hijacker
%attr(555,root,root) /usr/libexec/syscare/c++-hijacker
%attr(555,root,root) /usr/libexec/syscare/gcc-hijacker
%attr(555,root,root) /usr/libexec/syscare/g++-hijacker
%attr(555,root,root) /usr/libexec/syscare/gnu-as-hijacker
%attr(555,root,root) /usr/libexec/syscare/gnu-compiler-hijacker
############################################
################ Change log ################
############################################
%changelog
* 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