update to 1.2.0-10

Sync patch
This commit is contained in:
ningyu 2023-12-28 16:05:41 +08:00
parent 13f63b2db3
commit 5909c8dc30
16 changed files with 4918 additions and 1 deletions

View File

@ -0,0 +1,31 @@
From 92f5334a547ddd7c1a8f787cdde7373965942835 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 8 Dec 2023 17:33:00 +0800
Subject: [PATCH 01/15] builder: fix 'enabling multiple kpatch may lead
soft-lockup' issue
Signed-off-by: renoseven <dev@renoseven.net>
---
builder/src/patch/kernel_patch/kpatch_builder.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/builder/src/patch/kernel_patch/kpatch_builder.rs b/builder/src/patch/kernel_patch/kpatch_builder.rs
index d0f58b4..69c0cee 100644
--- a/builder/src/patch/kernel_patch/kpatch_builder.rs
+++ b/builder/src/patch/kernel_patch/kpatch_builder.rs
@@ -212,9 +212,9 @@ impl KernelPatchBuilder {
fn parse_kbuild_cmd_envs(&self, build_root: &Path) -> ExternCommandEnvs {
ExternCommandEnvs::new()
.env("CACHEDIR", build_root)
- .env("NO_PROFILING_CALLS", "1")
- .env("DISABLE_AFTER_LOAD", "1")
- .env("KEEP_JUMP_LABEL", "1")
+ .env("NO_PROFILING_CALLS", "yes")
+ .env("DISABLE_AFTER_LOAD", "yes")
+ .env("KEEP_JUMP_LABEL", "yes")
}
fn invoke_kpatch_build(
--
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
From bad9504ed575d86dd93ffcfdd466827cc3b3dadb Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 20 Dec 2023 10:46:44 +0800
Subject: [PATCH 03/15] upatch: remove upatch manage log file
1. remove /tmp/upatch-manage.log
2. print log to stdout
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-manage/log.h | 3 +--
upatch/upatch-manage/upatch-manage.c | 8 --------
2 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/upatch/upatch-manage/log.h b/upatch/upatch-manage/log.h
index 4d1fd7a..80fed3a 100644
--- a/upatch/upatch-manage/log.h
+++ b/upatch/upatch-manage/log.h
@@ -30,7 +30,6 @@
/* Files that include log.h must define loglevel and logprefix */
extern enum loglevel loglevel;
extern char *logprefix;
-extern FILE *upatch_manage_log_fd;
enum exit_status {
EXIT_STATUS_SUCCESS = 0,
@@ -58,7 +57,7 @@ enum exit_status {
#define log(level, format, ...) \
({ \
if (loglevel <= (level)) \
- fprintf(upatch_manage_log_fd, format, ##__VA_ARGS__); \
+ printf(format, ##__VA_ARGS__); \
})
#define REQUIRE(COND, message) \
diff --git a/upatch/upatch-manage/upatch-manage.c b/upatch/upatch-manage/upatch-manage.c
index b36ff0d..a109db7 100644
--- a/upatch/upatch-manage/upatch-manage.c
+++ b/upatch/upatch-manage/upatch-manage.c
@@ -124,8 +124,6 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
static struct argp argp = { options, parse_opt, args_doc, program_doc };
-FILE *upatch_manage_log_fd = NULL;
-
int patch_upatch(const char *uuid, const char *binary_path, const char *upatch_path, int pid)
{
struct upatch_elf uelf;
@@ -184,11 +182,6 @@ int main(int argc, char *argv[])
struct arguments args;
int ret;
- upatch_manage_log_fd = fopen("/tmp/upatch-manage.log", "w");
- if (upatch_manage_log_fd < 0) {
- return -1;
- }
-
memset(&args, 0, sizeof(struct arguments));
argp_parse(&argp, argc, argv, 0, NULL, &args);
if (args.verbose) {
@@ -217,6 +210,5 @@ int main(int argc, char *argv[])
break;
}
- fclose(upatch_manage_log_fd);
return abs(ret);
}
--
2.33.0

View File

@ -0,0 +1,25 @@
From 295f6f406b86b70142bed9b17abc56b72962ac3d Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 20 Dec 2023 12:18:11 +0800
Subject: [PATCH 04/15] upatch: remove redudant log output
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-tool/upatch-meta.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/upatch/upatch-tool/upatch-meta.c b/upatch/upatch-tool/upatch-meta.c
index cf60cff..c625115 100644
--- a/upatch/upatch-tool/upatch-meta.c
+++ b/upatch/upatch-tool/upatch-meta.c
@@ -573,7 +573,6 @@ patch_status_e meta_get_patch_status(const char *uuid)
}
patch = find_patch_by_uuid(uuid);
if (patch == NULL) {
- log_warn("can't find patch uuid:%s failed to get status\n", uuid);
return UPATCH_PATCH_STATUS_NOT_APPLIED;
}
return patch->status;
--
2.33.0

View File

@ -0,0 +1,32 @@
From 532e5680087cc1a69f88692c31e523e2eab70145 Mon Sep 17 00:00:00 2001
From: ningyu <405888464@qq.com>
Date: Wed, 20 Dec 2023 15:34:13 +0800
Subject: [PATCH 05/15] upatch-manage: close dup fd
---
upatch/upatch-manage/upatch-process.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/upatch/upatch-manage/upatch-process.c b/upatch/upatch-manage/upatch-process.c
index aeb5705..2216db2 100644
--- a/upatch/upatch-manage/upatch-process.c
+++ b/upatch/upatch-manage/upatch-process.c
@@ -518,6 +518,7 @@ int upatch_process_parse_proc_maps(struct upatch_process *proc)
} while (1);
fclose(f);
+ close(fd);
log_debug("Found %d object file(s)\n", proc->num_objs);
@@ -531,6 +532,7 @@ int upatch_process_parse_proc_maps(struct upatch_process *proc)
error:
fclose(f);
+ close(fd);
return -1;
}
--
2.33.0

View File

@ -0,0 +1,252 @@
From fdb0d2ab35085bd97d5cae420df0a2c9c6f99c0a Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 22 Dec 2023 13:40:29 +0800
Subject: [PATCH 06/15] daemon: check patch before patch restoration
Signed-off-by: renoseven <dev@renoseven.net>
---
daemon/src/patch/manager/driver/kpatch/mod.rs | 37 +++++++++---
daemon/src/patch/manager/driver/mod.rs | 2 +-
daemon/src/patch/manager/driver/upatch/mod.rs | 58 +++++++++++++------
daemon/src/patch/manager/mod.rs | 3 +-
daemon/src/patch/transaction.rs | 2 +-
daemon/src/rpc/skeleton_impl/patch.rs | 2 +-
6 files changed, 73 insertions(+), 31 deletions(-)
diff --git a/daemon/src/patch/manager/driver/kpatch/mod.rs b/daemon/src/patch/manager/driver/kpatch/mod.rs
index 57aa127..efe80e5 100644
--- a/daemon/src/patch/manager/driver/kpatch/mod.rs
+++ b/daemon/src/patch/manager/driver/kpatch/mod.rs
@@ -2,7 +2,7 @@ use std::{ffi::OsString, os::unix::prelude::OsStrExt, path::Path};
use anyhow::{anyhow, bail, ensure, Context, Result};
use lazy_static::lazy_static;
-use log::{debug, warn};
+use log::debug;
use syscare_abi::PatchStatus;
use syscare_common::{
@@ -87,15 +87,10 @@ impl KernelPatchDriver {
}
}
-impl PatchDriver for KernelPatchDriver {
- fn check(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
+impl KernelPatchDriver {
+ fn check_compatiblity(&self, patch: &Patch) -> Result<()> {
const KERNEL_NAME_PREFIX: &str = "kernel-";
- if flag == PatchOpFlag::SkipCheck {
- warn!("Skipped patch \"{}\" check", patch);
- return Ok(());
- }
-
let kernel_version = os::kernel::version();
let current_kernel = OsString::from(KERNEL_NAME_PREFIX).concat(kernel_version);
@@ -113,18 +108,42 @@ impl PatchDriver for KernelPatchDriver {
);
}
+ Ok(())
+ }
+
+ fn check_consistency(&self, patch: &Patch) -> Result<()> {
let patch_ext: &KernelPatchExt = (&patch.info_ext).into();
let patch_file = patch_ext.patch_file.as_path();
let real_checksum = digest::file(patch_file)?;
+ debug!("Target checksum: {}", patch.checksum);
+ debug!("Expected checksum: {}", real_checksum);
+
ensure!(
patch.checksum.eq(&real_checksum),
- "Kpatch: Patch file \"{}\" checksum failed",
+ "Kpatch: Patch \"{}\" consistency check failed",
patch_file.display()
);
Ok(())
}
+ fn check_confliction(&self, _patch: &Patch) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl PatchDriver for KernelPatchDriver {
+ fn check(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
+ self.check_compatiblity(patch)?;
+ self.check_consistency(patch)?;
+
+ if flag != PatchOpFlag::Force {
+ self.check_confliction(patch)?;
+ }
+
+ Ok(())
+ }
+
fn status(&self, patch: &Patch, _flag: PatchOpFlag) -> Result<PatchStatus> {
Self::get_patch_status(patch)
}
diff --git a/daemon/src/patch/manager/driver/mod.rs b/daemon/src/patch/manager/driver/mod.rs
index 9beb999..c3a4ca4 100644
--- a/daemon/src/patch/manager/driver/mod.rs
+++ b/daemon/src/patch/manager/driver/mod.rs
@@ -13,7 +13,7 @@ use super::entity::*;
#[derive(PartialEq, Clone, Copy)]
pub enum PatchOpFlag {
Normal,
- SkipCheck,
+ Force,
}
/// Basic abstraction of patch operation
diff --git a/daemon/src/patch/manager/driver/upatch/mod.rs b/daemon/src/patch/manager/driver/upatch/mod.rs
index 993c116..e4a914b 100644
--- a/daemon/src/patch/manager/driver/upatch/mod.rs
+++ b/daemon/src/patch/manager/driver/upatch/mod.rs
@@ -1,6 +1,5 @@
use std::{
- ffi::OsString,
- os::unix::prelude::OsStringExt,
+ ffi::CStr,
path::{Path, PathBuf},
};
@@ -9,7 +8,7 @@ use anyhow::{anyhow, bail, ensure, Result};
use indexmap::IndexMap;
use lazy_static::lazy_static;
use libc::{c_char, EEXIST, EFAULT, ENOENT, EPERM};
-use log::{info, warn};
+use log::{debug, info};
use parking_lot::Mutex;
use syscare_abi::PatchStatus;
use syscare_common::util::digest;
@@ -92,25 +91,33 @@ impl UserPatchDriver {
}
}
-impl PatchDriver for UserPatchDriver {
- fn check(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
- const ERR_MSG_LEN: usize = 512;
-
- if flag == PatchOpFlag::SkipCheck {
- warn!("Skipped patch \"{}\" check", patch);
- return Ok(());
- }
+impl UserPatchDriver {
+ fn check_compatiblity(&self, _patch: &Patch) -> Result<()> {
+ Ok(())
+ }
+ fn check_consistency(&self, patch: &Patch) -> Result<()> {
let patch_ext: &UserPatchExt = (&patch.info_ext).into();
let patch_file = &patch_ext.patch_file;
let real_checksum = digest::file(patch_file).map_err(|e| anyhow!("Upatch: {}", e))?;
+ debug!("Target checksum: {}", patch.checksum);
+ debug!("Expected checksum: {}", real_checksum);
+
ensure!(
patch.checksum.eq(&real_checksum),
- "Upatch: Patch file \"{}\" checksum failed",
+ "Upatch: Patch \"{}\" consistency check failed",
patch_file.display()
);
+ Ok(())
+ }
+
+ fn check_confliction(&self, patch: &Patch) -> Result<()> {
+ const ERR_MSG_LEN: usize = 512;
+
+ let patch_ext: &UserPatchExt = (&patch.info_ext).into();
+
let target_elf = patch_ext.target_elf.to_cstring()?;
let patch_file = patch_ext.patch_file.to_cstring()?;
let mut msg_buf = vec![0; ERR_MSG_LEN];
@@ -123,11 +130,28 @@ impl PatchDriver for UserPatchDriver {
msg_buf.capacity(),
)
};
+ if ret_val != 0 {
+ match CStr::from_bytes_until_nul(&msg_buf) {
+ Ok(err_msg) => bail!(format!("Upatch: {}", err_msg.to_string_lossy())),
+ Err(_) => bail!(format!(
+ "Upatch: {}",
+ std::io::Error::from_raw_os_error(ret_val)
+ )),
+ }
+ }
- ensure!(
- ret_val == 0,
- OsString::from_vec(msg_buf).to_string_lossy().to_string()
- );
+ Ok(())
+ }
+}
+
+impl PatchDriver for UserPatchDriver {
+ fn check(&self, patch: &Patch, flag: PatchOpFlag) -> Result<()> {
+ self.check_compatiblity(patch)?;
+ self.check_consistency(patch)?;
+
+ if flag != PatchOpFlag::Force {
+ self.check_confliction(patch)?;
+ }
Ok(())
}
@@ -151,7 +175,7 @@ impl PatchDriver for UserPatchDriver {
patch_uuid.as_ptr(),
target_elf.as_ptr(),
patch_file.as_ptr(),
- matches!(flag, PatchOpFlag::SkipCheck),
+ matches!(flag, PatchOpFlag::Force),
)
};
diff --git a/daemon/src/patch/manager/mod.rs b/daemon/src/patch/manager/mod.rs
index 3b1aa8c..fdb218d 100644
--- a/daemon/src/patch/manager/mod.rs
+++ b/daemon/src/patch/manager/mod.rs
@@ -267,8 +267,7 @@ impl PatchManager {
"Restore patch \"{}\" status to \"{}\"",
patch, target_status
);
- if let Err(e) = self.do_status_transition(&patch, target_status, PatchOpFlag::SkipCheck)
- {
+ if let Err(e) = self.do_status_transition(&patch, target_status, PatchOpFlag::Force) {
error!("{}", e);
}
}
diff --git a/daemon/src/patch/transaction.rs b/daemon/src/patch/transaction.rs
index 16bab46..079b024 100644
--- a/daemon/src/patch/transaction.rs
+++ b/daemon/src/patch/transaction.rs
@@ -70,7 +70,7 @@ where
fn rollback(&mut self) -> Result<()> {
let mut patch_manager = self.patch_manager.write();
while let Some((patch, status)) = self.finish_list.pop() {
- patch_manager.do_status_transition(&patch, status, PatchOpFlag::SkipCheck)?;
+ patch_manager.do_status_transition(&patch, status, PatchOpFlag::Force)?;
}
Ok(())
}
diff --git a/daemon/src/rpc/skeleton_impl/patch.rs b/daemon/src/rpc/skeleton_impl/patch.rs
index 4517a03..8d4f57b 100644
--- a/daemon/src/rpc/skeleton_impl/patch.rs
+++ b/daemon/src/rpc/skeleton_impl/patch.rs
@@ -82,7 +82,7 @@ impl PatchSkeleton for PatchSkeletonImpl {
PatchManager::apply_patch,
match force {
false => PatchOpFlag::Normal,
- true => PatchOpFlag::SkipCheck,
+ true => PatchOpFlag::Force,
},
identifier,
)?
--
2.33.0

View File

@ -0,0 +1,217 @@
From 727ece331961c5a495350b38afa982f1598e5b82 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 22 Dec 2023 13:45:48 +0800
Subject: [PATCH 07/15] upatch: elf verification
Signed-off-by: renoseven <dev@renoseven.net>
---
daemon/src/patch/manager/driver/upatch/mod.rs | 4 +-
upatch/upatch-manage/upatch-elf.c | 7 ++
upatch/upatch-tool/log.h | 1 +
upatch/upatch-tool/upatch-elf.c | 102 ++++++++++--------
upatch/upatch-tool/upatch-tool-lib.c | 9 +-
5 files changed, 72 insertions(+), 51 deletions(-)
diff --git a/daemon/src/patch/manager/driver/upatch/mod.rs b/daemon/src/patch/manager/driver/upatch/mod.rs
index e4a914b..4d06e84 100644
--- a/daemon/src/patch/manager/driver/upatch/mod.rs
+++ b/daemon/src/patch/manager/driver/upatch/mod.rs
@@ -7,7 +7,7 @@ use anyhow::{anyhow, bail, ensure, Result};
use indexmap::IndexMap;
use lazy_static::lazy_static;
-use libc::{c_char, EEXIST, EFAULT, ENOENT, EPERM};
+use libc::{c_char, EEXIST, EFAULT, ENOENT, ENOEXEC, EPERM};
use log::{debug, info};
use parking_lot::Mutex;
use syscare_abi::PatchStatus;
@@ -182,7 +182,7 @@ impl PatchDriver for UserPatchDriver {
match ret_val {
0 => Ok(()),
EPERM => bail!("Upatch: Operation not permitted"),
- ENOENT => bail!("Upatch: Patch symbol is empty"),
+ ENOEXEC => bail!("Upatch: Patch format error"),
EEXIST => bail!("Upatch: Patch is already exist"),
_ => bail!("Upatch: {}", std::io::Error::from_raw_os_error(ret_val)),
}
diff --git a/upatch/upatch-manage/upatch-elf.c b/upatch/upatch-manage/upatch-elf.c
index 2bd3175..31180b5 100644
--- a/upatch/upatch-manage/upatch-elf.c
+++ b/upatch/upatch-manage/upatch-elf.c
@@ -67,6 +67,13 @@ static int open_elf(struct elf_info *einfo, const char *name)
einfo->shdrs = (void *)einfo->hdr + einfo->hdr->e_shoff;
einfo->shstrtab = (void *)einfo->hdr + einfo->shdrs[einfo->hdr->e_shstrndx].sh_offset;
+ void *einfo_eof = einfo->hdr + einfo->patch_size;
+ if ((void *)einfo->shdrs > einfo_eof || (void *)einfo->shstrtab > einfo_eof) {
+ log_error("File '%s' is not a valid elf\n", name);
+ ret = -ENOEXEC;
+ goto out;
+ }
+
for (i = 0; i < einfo->hdr->e_shnum; ++i) {
sec_name = einfo->shstrtab + einfo->shdrs[i].sh_name;
if (streql(sec_name, BUILD_ID_NAME) && einfo->shdrs[i].sh_type == SHT_NOTE) {
diff --git a/upatch/upatch-tool/log.h b/upatch/upatch-tool/log.h
index 75213d8..e42e290 100644
--- a/upatch/upatch-tool/log.h
+++ b/upatch/upatch-tool/log.h
@@ -11,5 +11,6 @@
#define log_debug(format, ...) log(DEBUG, format, ##__VA_ARGS__)
#define log_normal(format, ...) log(NORMAL, format, ##__VA_ARGS__)
#define log_warn(format, ...) log(WARN, format, ##__VA_ARGS__)
+#define log_error(format, ...) log(ERR, format, ##__VA_ARGS__)
#endif
diff --git a/upatch/upatch-tool/upatch-elf.c b/upatch/upatch-tool/upatch-elf.c
index 5b9b0bd..def536c 100644
--- a/upatch/upatch-tool/upatch-elf.c
+++ b/upatch/upatch-tool/upatch-elf.c
@@ -44,53 +44,65 @@ out:
static int open_elf(struct elf_info *einfo, const char *name)
{
- int ret = 0, fd = -1, i;
- char *sec_name;
- struct stat st;
-
- // TODO: check ELF
- fd = open(name, O_RDONLY);
- if (fd == -1)
- log_warn("open %s failed with errno %d \n", name, errno);
+ int ret = 0, fd = -1, i;
+ char *sec_name;
+ struct stat st;
+
+ fd = open(name, O_RDONLY);
+ if (fd == -1) {
+ ret = -errno;
+ log_error("Failed to open file '%s', ret=%d\n", name, ret);
+ goto out;
+ }
+
+ ret = stat(name, &st);
+ if (ret != 0) {
+ ret = -errno;
+ log_error("Failed to stat file '%s', ret=%d\n", name, ret);
+ goto out;
+ }
+
+ ret = read_from_offset(fd, (void **)&einfo->patch_buff, st.st_size, 0);
+ if (ret != 0) {
+ log_error("Failed to read file '%s', ret=%d\n", name, ret);
+ goto out;
+ }
+
+ einfo->name = name;
+ einfo->inode = st.st_ino;
+ einfo->patch_size = st.st_size;
+ einfo->hdr = (void *)einfo->patch_buff;
+ einfo->shdrs = (void *)einfo->hdr + einfo->hdr->e_shoff;
+ einfo->shstrtab = (void *)einfo->hdr + einfo->shdrs[einfo->hdr->e_shstrndx].sh_offset;
+
+ void *einfo_eof = einfo->hdr + einfo->patch_size;
+ if ((void *)einfo->shdrs > einfo_eof || (void *)einfo->shstrtab > einfo_eof) {
+ log_error("File '%s' is not a valid elf\n", name);
+ ret = -ENOEXEC;
+ goto out;
+ }
+
+ for (i = 0; i < einfo->hdr->e_shnum; ++i) {
+ sec_name = einfo->shstrtab + einfo->shdrs[i].sh_name;
+ if (streql(sec_name, BUILD_ID_NAME) && einfo->shdrs[i].sh_type == SHT_NOTE) {
+ einfo->num_build_id = i;
+ break;
+ }
+ }
+
+ if (einfo->num_build_id == 0) {
+ ret = -EINVAL;
+ log_error("Cannot find section '%s'\n", BUILD_ID_NAME);
+ goto out;
+ }
+
+ ret = 0;
- ret = stat(name, &st);
- if (ret)
- log_warn("get %s stat failed with errno %d \n", name, errno);
-
- ret = read_from_offset(fd, (void **)&einfo->patch_buff, st.st_size, 0);
- if (ret)
- goto out;
-
- einfo->name = name;
- einfo->inode = st.st_ino;
- einfo->patch_size = st.st_size;
- einfo->hdr = (void *)einfo->patch_buff;
- einfo->shdrs = (void *)einfo->hdr + einfo->hdr->e_shoff;
- einfo->shstrtab = (void *)einfo->hdr +
- einfo->shdrs[einfo->hdr->e_shstrndx].sh_offset;
-
- for (i = 0; i < einfo->hdr->e_shnum; ++i) {
- sec_name = einfo->shstrtab + einfo->shdrs[i].sh_name;
- if (streql(sec_name, BUILD_ID_NAME) &&
- einfo->shdrs[i].sh_type == SHT_NOTE) {
- einfo->num_build_id = i;
- break;
- }
- }
-
- if (einfo->num_build_id == 0) {
- ret = EINVAL;
- log_warn("no %s found \n", BUILD_ID_NAME);
- goto out;
- }
-
- log_warn("no %ld found \n", einfo->inode);
-
- ret = 0;
out:
- if (fd != -1)
- close(fd);
- return ret;
+ if (fd > 0) {
+ close(fd);
+ }
+ return ret;
}
int upatch_init(struct upatch_elf *uelf, const char *name)
diff --git a/upatch/upatch-tool/upatch-tool-lib.c b/upatch/upatch-tool/upatch-tool-lib.c
index 4f816bb..4e5bda1 100644
--- a/upatch/upatch-tool/upatch-tool-lib.c
+++ b/upatch/upatch-tool/upatch-tool-lib.c
@@ -22,7 +22,8 @@ int upatch_check(const char *target_elf, const char *patch_file, char *err_msg,
{
struct list_head *patch_syms = patch_symbols_resolve(target_elf, patch_file);
if (patch_syms == NULL) {
- return ENOENT;
+ snprintf(err_msg, max_len, "Patch format error");
+ return ENOEXEC;
}
struct list_head *collision_list = meta_get_symbol_collision(target_elf, patch_syms);
@@ -30,7 +31,7 @@ int upatch_check(const char *target_elf, const char *patch_file, char *err_msg,
return 0;
}
- int offset = snprintf(err_msg, max_len, "Upatch: Patch is conflicted with ");
+ int offset = snprintf(err_msg, max_len, "Patch is conflicted with ");
symbol_collision *collision = NULL;
list_for_each_entry(collision, collision_list, self) {
err_msg += offset;
@@ -61,8 +62,8 @@ int upatch_load(const char *uuid, const char *target, const char *patch, bool fo
// Resolve patch symbols
struct list_head *patch_syms = patch_symbols_resolve(target, patch);
if (patch_syms == NULL) {
- log_warn("{%s}: Patch symbol is empty\n", uuid);
- return ENOENT;
+ log_warn("{%s}: Patch format error\n", uuid);
+ return ENOEXEC;
}
// Check patch symbol collision
--
2.33.0

View File

@ -0,0 +1,42 @@
From b23af1223e0a284a6dd603ed21c60612170d6767 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Mon, 18 Dec 2023 18:34:52 +0800
Subject: [PATCH 08/15] upatch: check build id
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-tool/upatch-resolve.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/upatch/upatch-tool/upatch-resolve.c b/upatch/upatch-tool/upatch-resolve.c
index d12bdae..aeb655c 100644
--- a/upatch/upatch-tool/upatch-resolve.c
+++ b/upatch/upatch-tool/upatch-resolve.c
@@ -65,18 +65,22 @@ struct list_head* patch_symbols_resolve(const char *target_elf, const char *patc
INIT_LIST_HEAD(head);
int ret = upatch_init(&uelf, patch_file);
-
if (ret < 0) {
log_warn("upatch-resolve: upatch_init failed\n");
goto out;
}
ret = binary_init(&relf, target_elf);
- if (ret) {
+ if (ret < 0) {
log_warn("upatch-resolve: binary_init failed %d \n", ret);
goto out;
}
+ if (check_build_id(&uelf.info, &relf.info) == false) {
+ log_error("upatch-resolve: Build id mismatched!\n");
+ goto out;
+ }
+
uelf.relf = &relf;
upatch_shdr = &uelf.info.shdrs[uelf.index.upatch_funcs];
upatch_funcs = uelf.info.patch_buff + upatch_shdr->sh_offset;
--
2.33.0

View File

@ -0,0 +1,38 @@
From bbfe75e66815319360af6e3773d78862ee7e65cc Mon Sep 17 00:00:00 2001
From: ningyu <ningyu9@huawei.com>
Date: Fri, 22 Dec 2023 06:33:51 +0000
Subject: [PATCH 09/15] README: add example for kernel module patch build
---
README.md | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6c3728b..e86d063 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,20 @@ $ syscare build \
--source ./redis-6.2.5-1.src.rpm \
--debuginfo ./redis-debuginfo-6.2.5-1.x86_64.rpm \
--output ./output \
- ./0001-Prevent-unauthenticated-client-from-easily-consuming.patch
+ --patch ./0001-Prevent-unauthenticated-client-from-easily-consuming.patch
+```
+
+### 内核模块热补丁制作
+```
+$ syscare build \
+ --patch-name HP001 \
+ --source ./kernel-5.10.0-60.91.0.115.src.rpm \
+ --source ./testmod-1-1.src.rpm \
+ --debuginfo ./kernel-debuginfo-5.10.0-60.91.0.115.aarch64.rpm \
+ --output ./output \
+ --verbose \
+ --skip-cleanup \
+ --patch ./0001-test.patch
```
补丁制作详细使用说明请见[build/README.md](https://gitee.com/openeuler/syscare/blob/master/build/README.md)
--
2.33.0

View File

@ -0,0 +1,41 @@
From ed7492d5090a249c50c49501e8865c05de481c94 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 22 Dec 2023 15:22:03 +0800
Subject: [PATCH 10/15] daemon: fix check build id logic
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-tool/upatch-elf.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/upatch/upatch-tool/upatch-elf.c b/upatch/upatch-tool/upatch-elf.c
index def536c..730c3bd 100644
--- a/upatch/upatch-tool/upatch-elf.c
+++ b/upatch/upatch-tool/upatch-elf.c
@@ -201,11 +201,18 @@ out:
bool check_build_id(struct elf_info *uelf, struct elf_info *relf)
{
- return uelf->shdrs[uelf->num_build_id].sh_size ==
- relf->shdrs[relf->num_build_id].sh_size &&
- !memcmp(uelf->hdr + uelf->shdrs[uelf->num_build_id].sh_offset,
- relf->hdr + relf->shdrs[relf->num_build_id].sh_offset,
- uelf->shdrs[uelf->num_build_id].sh_size);
+ if (uelf->shdrs[uelf->num_build_id].sh_size != relf->shdrs[relf->num_build_id].sh_size) {
+ return false;
+ }
+
+ void* uelf_build_id = (void *)uelf->hdr + uelf->shdrs[uelf->num_build_id].sh_offset;
+ void* relf_build_id = (void *)relf->hdr + relf->shdrs[relf->num_build_id].sh_offset;
+ size_t build_id_len = uelf->shdrs[uelf->num_build_id].sh_size;
+
+ if (memcmp(uelf_build_id, relf_build_id, build_id_len) != 0) {
+ return false;
+ }
+ return true;
}
void binary_close(struct running_elf *relf)
--
2.33.0

View File

@ -0,0 +1,40 @@
From b4a11e983c78d7f856a551e058b84c0ea4bde8c7 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Mon, 18 Dec 2023 20:20:19 +0800
Subject: [PATCH 11/15] upatch-diff: fix a nullptr issue
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-diff/elf-correlate.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/upatch/upatch-diff/elf-correlate.c b/upatch/upatch-diff/elf-correlate.c
index 2dd665c..0773016 100644
--- a/upatch/upatch-diff/elf-correlate.c
+++ b/upatch/upatch-diff/elf-correlate.c
@@ -116,11 +116,13 @@ static void correlate_section(struct section *sec_orig, struct section *sec_patc
__correlate_section(sec_orig->rela, sec_patched->rela);
}
- if (sec_orig->secsym)
+ if (sec_orig->secsym && sec_patched->secsym) {
correlate_symbol(sec_orig->secsym, sec_patched->secsym);
+ }
- if (sec_orig->sym)
+ if (sec_orig->sym) {
correlate_symbol(sec_orig->sym, sec_patched->sym);
+ }
}
void upatch_correlate_sections(struct upatch_elf *uelf_source, struct upatch_elf *uelf_patched)
@@ -397,4 +399,4 @@ void upatch_correlate_static_local_variables(struct upatch_elf *uelf_source, str
}
return check_static_variable_correlate(uelf_source, uelf_patched);
-}
\ No newline at end of file
+}
--
2.33.0

View File

@ -0,0 +1,49 @@
From d6ca7e72c9ab04bcebbd557e08f795dbbba1dc8a Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Fri, 22 Dec 2023 18:04:50 +0800
Subject: [PATCH 12/15] daemon: fix rust 1.60 compile issue
Signed-off-by: renoseven <dev@renoseven.net>
---
daemon/src/patch/manager/driver/upatch/mod.rs | 21 +++++++------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/daemon/src/patch/manager/driver/upatch/mod.rs b/daemon/src/patch/manager/driver/upatch/mod.rs
index 4d06e84..191b327 100644
--- a/daemon/src/patch/manager/driver/upatch/mod.rs
+++ b/daemon/src/patch/manager/driver/upatch/mod.rs
@@ -1,7 +1,4 @@
-use std::{
- ffi::CStr,
- path::{Path, PathBuf},
-};
+use std::path::{Path, PathBuf};
use anyhow::{anyhow, bail, ensure, Result};
@@ -130,15 +127,13 @@ impl UserPatchDriver {
msg_buf.capacity(),
)
};
- if ret_val != 0 {
- match CStr::from_bytes_until_nul(&msg_buf) {
- Ok(err_msg) => bail!(format!("Upatch: {}", err_msg.to_string_lossy())),
- Err(_) => bail!(format!(
- "Upatch: {}",
- std::io::Error::from_raw_os_error(ret_val)
- )),
- }
- }
+ ensure!(
+ ret_val == 0,
+ format!(
+ "Upatch: {}",
+ String::from_utf8_lossy(&msg_buf).trim_end_matches(|c| c == '\0')
+ )
+ );
Ok(())
}
--
2.33.0

View File

@ -0,0 +1,106 @@
From 5feeef470d6088cc03e04e4a8f750b6f3ae816ba Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Wed, 27 Dec 2023 17:17:16 +0800
Subject: [PATCH 13/15] upatchd: create config dir at startup
1. rename arg '--config-file' to '--config-dir'
2. try to create config directory at startup
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-daemon/src/args/matcher.rs | 4 ++--
upatch/upatch-daemon/src/args/mod.rs | 8 ++++----
upatch/upatch-daemon/src/main.rs | 7 ++++++-
3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/upatch/upatch-daemon/src/args/matcher.rs b/upatch/upatch-daemon/src/args/matcher.rs
index 66cf316..0badaf6 100644
--- a/upatch/upatch-daemon/src/args/matcher.rs
+++ b/upatch/upatch-daemon/src/args/matcher.rs
@@ -2,8 +2,8 @@ use clap::{clap_app, crate_description, crate_name, crate_version, AppSettings,
const DEFAULT_PID_FILE: &str = "/var/run/upatchd.pid";
const DEFAULT_SOCKET_FILE: &str = "/var/run/upatchd.sock";
-const DEFAULT_CONFIG_FILE: &str = "/etc/syscare/upatchd.yaml";
const DEFAULT_WORK_DIR: &str = "/var/run/syscare";
+const DEFAULT_CONFIG_DIR: &str = "/etc/syscare";
const DEFAULT_LOG_DIR: &str = "/var/log/syscare";
const DEFAULT_LOG_LEVEL: &str = "info";
@@ -24,7 +24,7 @@ impl ArgMatcher {
(@arg daemon: short("d") long("daemon") "Run as a daemon")
(@arg pid_file: long("pid-file") +takes_value value_name("PID_FILE") default_value(DEFAULT_PID_FILE) "Path for daemon pid file")
(@arg socket_file: long("socket-file") +takes_value value_name("SOCKET_FILE") default_value(DEFAULT_SOCKET_FILE) "Path for daemon unix socket")
- (@arg config_file: long("config-file") +takes_value value_name("CONFIG_FILE") default_value(DEFAULT_CONFIG_FILE) "Path for daemon config file")
+ (@arg config_file: long("config-dir") +takes_value value_name("CONFIG_DIR") default_value(DEFAULT_CONFIG_DIR) "Daemon config directory")
(@arg work_dir: long("work-dir") +takes_value value_name("WORK_DIR") default_value(DEFAULT_WORK_DIR) "Daemon working directory")
(@arg log_dir: long("log-dir") +takes_value value_name("LOG_DIR") default_value(DEFAULT_LOG_DIR) "Daemon logging directory")
(@arg log_level: short("l") long("log-level") +takes_value value_name("LOG_LEVEL") default_value(DEFAULT_LOG_LEVEL) "Set the logging level (\"trace\"|\"debug\"|\"info\"|\"warn\"|\"error\")")
diff --git a/upatch/upatch-daemon/src/args/mod.rs b/upatch/upatch-daemon/src/args/mod.rs
index e20d66b..318470e 100644
--- a/upatch/upatch-daemon/src/args/mod.rs
+++ b/upatch/upatch-daemon/src/args/mod.rs
@@ -23,8 +23,8 @@ pub struct Arguments {
/// Path for daemon unix socket
pub socket_file: PathBuf,
- /// Path for daemon configuration file
- pub config_file: PathBuf,
+ /// Daemon config directory
+ pub config_dir: PathBuf,
/// Daemon working directory
pub work_dir: PathBuf,
@@ -45,7 +45,7 @@ impl Parser<'_> for Arguments {
daemon: ArgParserImpl::is_present(matches, "daemon"),
pid_file: ArgParserImpl::parse_arg(matches, "pid_file")?,
socket_file: ArgParserImpl::parse_arg(matches, "socket_file")?,
- config_file: ArgParserImpl::parse_arg(matches, "config_file")?,
+ config_dir: ArgParserImpl::parse_arg(matches, "config_dir")?,
work_dir: ArgParserImpl::parse_arg(matches, "work_dir")?,
log_dir: ArgParserImpl::parse_arg(matches, "log_dir")?,
log_level: ArgParserImpl::parse_arg(matches, "log_level")?,
@@ -64,7 +64,7 @@ impl Arguments {
fn normalize_pathes(mut self) -> Result<Self> {
self.pid_file = fs::normalize(&self.pid_file)?;
self.socket_file = fs::normalize(&self.socket_file)?;
- self.config_file = fs::normalize(&self.config_file)?;
+ self.config_dir = fs::normalize(&self.config_dir)?;
self.work_dir = fs::normalize(self.work_dir)?;
self.log_dir = fs::normalize(&self.log_dir)?;
diff --git a/upatch/upatch-daemon/src/main.rs b/upatch/upatch-daemon/src/main.rs
index cda98b2..80c292f 100644
--- a/upatch/upatch-daemon/src/main.rs
+++ b/upatch/upatch-daemon/src/main.rs
@@ -28,6 +28,8 @@ use args::Arguments;
use logger::Logger;
use rpc::{Skeleton, SkeletonImpl};
+const CONFIG_FILE_NAME: &str = "upatchd.yaml";
+
const DAEMON_VERSION: &str = env!("CARGO_PKG_VERSION");
const DAEMON_UMASK: u32 = 0o027;
const DAEMON_PARK_TIMEOUT: u64 = 100;
@@ -67,6 +69,8 @@ impl Daemon {
}
fn prepare_environment(&self) -> Result<()> {
+ self.prepare_directory(&self.args.config_dir)?;
+
self.prepare_directory(&self.args.work_dir)?;
self.prepare_directory(&self.args.log_dir)?;
Ok(())
@@ -99,7 +103,8 @@ impl Daemon {
fn initialize_skeleton(&self) -> Result<IoHandler> {
let mut io_handler = IoHandler::new();
- io_handler.extend_with(SkeletonImpl::new(&self.args.config_file)?.to_delegate());
+ let config_file = self.args.config_dir.join(CONFIG_FILE_NAME);
+ io_handler.extend_with(SkeletonImpl::new(config_file)?.to_delegate());
Ok(io_handler)
}
--
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,363 @@
From 4bac002ec33f3593ef03ff01494b524234c40484 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 26 Dec 2023 13:07:53 +0800
Subject: [PATCH 15/15] upatch: fix memory leak
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-manage/upatch-patch.c | 4 +-
upatch/upatch-tool/upatch-meta.c | 8 ++-
upatch/upatch-tool/upatch-resolve.c | 63 +++++++---------
upatch/upatch-tool/upatch-resolve.h | 3 +-
upatch/upatch-tool/upatch-tool-lib.c | 104 +++++++++++++++++++++------
5 files changed, 117 insertions(+), 65 deletions(-)
diff --git a/upatch/upatch-manage/upatch-patch.c b/upatch/upatch-manage/upatch-patch.c
index 762641c..4763778 100644
--- a/upatch/upatch-manage/upatch-patch.c
+++ b/upatch/upatch-manage/upatch-patch.c
@@ -590,8 +590,8 @@ static int upatch_apply_patches(struct upatch_process *proc,
if (!found) {
ret = -1;
- log_debug("can't found inode %lu in pid %d\n",
- uelf->relf->info.inode, proc->pid);
+ log_debug("Cannot find inode %lu in pid %d, file is not loaded\n",
+ uelf->relf->info.inode, proc->pid);
goto out;
}
diff --git a/upatch/upatch-tool/upatch-meta.c b/upatch/upatch-tool/upatch-meta.c
index c625115..2bd39b4 100644
--- a/upatch/upatch-tool/upatch-meta.c
+++ b/upatch/upatch-tool/upatch-meta.c
@@ -197,9 +197,11 @@ static int patch_deactive_in_cover(struct upatch_meta_patch *patch)
static int list_add_symbol(struct list_head *head, struct upatch_meta_symbol *sym)
{
struct upatch_meta_symbol *newsym = (struct upatch_meta_symbol *)malloc(sizeof(struct upatch_meta_symbol));
- if (newsym == NULL)
+ if (newsym == NULL) {
return ENOMEM;
+ }
memset(newsym, 0, sizeof(struct upatch_meta_symbol));
+
strncpy(newsym->name, sym->name, sizeof(newsym->name));
newsym->offset = sym->offset;
INIT_LIST_HEAD(&newsym->self);
@@ -212,9 +214,11 @@ static int list_add_symbol(struct list_head *head, struct upatch_meta_symbol *sy
static int list_add_symbol_for_patch(struct upatch_meta_patch *patch, struct list_head *head, struct upatch_meta_symbol *sym)
{
struct upatch_meta_symbol *newsym = (struct upatch_meta_symbol *)malloc(sizeof(struct upatch_meta_symbol));
- if (newsym == NULL)
+ if (newsym == NULL) {
return ENOMEM;
+ }
memset(newsym, 0, sizeof(struct upatch_meta_symbol));
+
strncpy(newsym->name, sym->name, sizeof(newsym->name));
newsym->offset = sym->offset;
INIT_LIST_HEAD(&newsym->self);
diff --git a/upatch/upatch-tool/upatch-resolve.c b/upatch/upatch-tool/upatch-resolve.c
index aeb655c..e9d75e0 100644
--- a/upatch/upatch-tool/upatch-resolve.c
+++ b/upatch/upatch-tool/upatch-resolve.c
@@ -42,79 +42,66 @@ out:
static int list_add_symbol(struct list_head *head, patch_symbols_t *sym)
{
patch_symbols_t *newsym = (patch_symbols_t *)malloc(sizeof(patch_symbols_t));
- if (newsym == NULL)
+ if (newsym == NULL) {
return ENOMEM;
+ }
memset(newsym, 0, sizeof(patch_symbols_t));
strncpy(newsym->name, sym->name, sizeof(newsym->name));
newsym->offset = sym->offset;
INIT_LIST_HEAD(&newsym->self);
list_add(&newsym->self, head);
+
return 0;
}
-struct list_head* patch_symbols_resolve(const char *target_elf, const char *patch_file) {
- struct upatch_elf uelf;
- struct running_elf relf;
- GElf_Shdr *upatch_shdr = NULL;
- struct upatch_patch_func *upatch_funcs = NULL;
- GElf_Off min_addr; // binary base
- int num;
- struct list_head *head = malloc(sizeof(struct list_head));
+struct list_head* patch_symbols_resolve(struct upatch_elf *uelf, struct running_elf *relf) {
+ struct list_head *head = NULL;
- INIT_LIST_HEAD(head);
-
- int ret = upatch_init(&uelf, patch_file);
- if (ret < 0) {
- log_warn("upatch-resolve: upatch_init failed\n");
- goto out;
- }
-
- ret = binary_init(&relf, target_elf);
- if (ret < 0) {
- log_warn("upatch-resolve: binary_init failed %d \n", ret);
- goto out;
- }
-
- if (check_build_id(&uelf.info, &relf.info) == false) {
+ if (check_build_id(&uelf->info, &relf->info) == false) {
log_error("upatch-resolve: Build id mismatched!\n");
goto out;
}
- uelf.relf = &relf;
- upatch_shdr = &uelf.info.shdrs[uelf.index.upatch_funcs];
- upatch_funcs = uelf.info.patch_buff + upatch_shdr->sh_offset;
- min_addr = calculate_load_address(uelf.relf, false);
+ GElf_Shdr *upatch_shdr = &uelf->info.shdrs[uelf->index.upatch_funcs];
+ GElf_Off min_addr = calculate_load_address(uelf->relf, false);
if (min_addr == (GElf_Off)-1) {
goto out;
}
- num = upatch_shdr->sh_size / sizeof(*upatch_funcs);
+ struct upatch_patch_func *upatch_funcs = uelf->info.patch_buff + upatch_shdr->sh_offset;
+ int num = upatch_shdr->sh_size / sizeof(*upatch_funcs);
log_debug("upatch-resolve: sh_size %lu, sizeof %lu \n", upatch_shdr->sh_size, sizeof(*upatch_funcs));
log_debug("upatch-resolve: elf base addr is 0x%lx, num is %d\n", min_addr, num);
+ head = malloc(sizeof(struct list_head));
+ INIT_LIST_HEAD(head);
+
for (int i = 0; i < num; i++) {
- patch_symbols_t *sym = malloc(sizeof(patch_symbols_t));
- sprintf(sym->name, "sym_%d", i);
- sym->offset = upatch_funcs[i].old_addr - min_addr;;
- log_debug("+upatch-resolve: sym->offset addr is 0x%lx\n", sym->offset);
- list_add_symbol(head, sym);
+ patch_symbols_t sym;
+
+ sprintf(sym.name, "sym_%d", i);
+ sym.offset = upatch_funcs[i].old_addr - min_addr;
+ log_debug("upatch-resolve: sym->offset addr is 0x%lx\n", sym.offset);
+
+ list_add_symbol(head, &sym); // This would copy the symbol
}
return head;
+
out:
- free(head);
+ if (head != NULL) {
+ free(head);
+ }
return NULL;
}
void patch_symbols_free(struct list_head *symbols) {
patch_symbols_t *sym, *next;
-
- if (!symbols)
- return;
list_for_each_entry_safe (sym, next, symbols, self) {
list_del(&sym->self);
free(sym);
}
+ free(symbols);
}
diff --git a/upatch/upatch-tool/upatch-resolve.h b/upatch/upatch-tool/upatch-resolve.h
index 7d0bb47..7c06345 100644
--- a/upatch/upatch-tool/upatch-resolve.h
+++ b/upatch/upatch-tool/upatch-resolve.h
@@ -2,8 +2,9 @@
#define __UPATCH_RESOLVE_H_
#include "list.h"
+#include "upatch-elf.h"
-struct list_head* patch_symbols_resolve(const char *target_elf, const char *patch_file);
+struct list_head* patch_symbols_resolve(struct upatch_elf *uelf, struct running_elf *relf);
void patch_symbols_free(struct list_head *symbols);
#endif
diff --git a/upatch/upatch-tool/upatch-tool-lib.c b/upatch/upatch-tool/upatch-tool-lib.c
index 4e5bda1..3731abe 100644
--- a/upatch/upatch-tool/upatch-tool-lib.c
+++ b/upatch/upatch-tool/upatch-tool-lib.c
@@ -14,21 +14,43 @@
#include "log.h"
#include "list.h"
+#include "upatch-elf.h"
#include "upatch-meta.h"
#include "upatch-resolve.h"
#include "upatch-ioctl.h"
int upatch_check(const char *target_elf, const char *patch_file, char *err_msg, size_t max_len)
{
- struct list_head *patch_syms = patch_symbols_resolve(target_elf, patch_file);
+ int ret = 0;
+ struct list_head *patch_syms = NULL;
+ struct list_head *collision_list = NULL;
+
+ struct upatch_elf uelf;
+ ret = upatch_init(&uelf, patch_file);
+ if (ret < 0) {
+ snprintf(err_msg, max_len, "Failed to read patch");
+ goto out;
+ }
+
+ struct running_elf relf;
+ ret = binary_init(&relf, target_elf);
+ if (ret < 0) {
+ snprintf(err_msg, max_len, "Failed to read target elf");
+ goto out;
+ }
+ uelf.relf = &relf;
+
+ patch_syms = patch_symbols_resolve(&uelf, &relf);
if (patch_syms == NULL) {
snprintf(err_msg, max_len, "Patch format error");
- return ENOEXEC;
+ ret = ENOEXEC;
+ goto out;
}
- struct list_head *collision_list = meta_get_symbol_collision(target_elf, patch_syms);
+ collision_list = meta_get_symbol_collision(target_elf, patch_syms);
if (collision_list == NULL) {
- return 0;
+ ret = 0;
+ goto out;
}
int offset = snprintf(err_msg, max_len, "Patch is conflicted with ");
@@ -39,50 +61,78 @@ int upatch_check(const char *target_elf, const char *patch_file, char *err_msg,
offset = snprintf(err_msg, max_len, "\"%s\" ", collision->uuid);
}
- patch_symbols_free(patch_syms);
- meta_put_symbol_collision(collision_list);
+out:
+ if (patch_syms != NULL) {
+ patch_symbols_free(patch_syms);
+ }
+ if (collision_list != NULL) {
+ meta_put_symbol_collision(collision_list);
+ }
+ binary_close(&relf);
+ upatch_close(&uelf);
- return EEXIST;
+ return ret;
}
int upatch_load(const char *uuid, const char *target, const char *patch, bool force)
{
+ int ret = 0;
+ struct list_head *patch_syms = NULL;
+ patch_entity_t *patch_entity = NULL;
+ struct list_head *collision_syms = NULL;
+
// Pointer check
if (uuid == NULL || target == NULL || patch == NULL) {
return EINVAL;
}
log_normal("Loading patch {%s} (\"%s\") for \"%s\"\n", uuid, patch, target);
+ struct upatch_elf uelf;
+ ret = upatch_init(&uelf, patch);
+ if (ret < 0) {
+ log_warn("Failed to read patch\n");
+ goto out;
+ }
+
+ struct running_elf relf;
+ ret = binary_init(&relf, target);
+ if (ret < 0) {
+ log_warn("Failed to read target elf\n");
+ goto out;
+ }
+ uelf.relf = &relf;
+
// Fails if patch is already exist
if (meta_get_patch_status(uuid) != UPATCH_PATCH_STATUS_NOT_APPLIED) {
log_warn("{%s}: Patch status is invalid\n", uuid);
- return EPERM;
+ ret = EPERM;
+ goto out;
}
// Resolve patch symbols
- struct list_head *patch_syms = patch_symbols_resolve(target, patch);
+ patch_syms = patch_symbols_resolve(&uelf, &relf);
if (patch_syms == NULL) {
log_warn("{%s}: Patch format error\n", uuid);
- return ENOEXEC;
+ ret = ENOEXEC;
+ goto out;
}
// Check patch symbol collision
if (!force) {
- struct list_head *collision_syms = meta_get_symbol_collision(target, patch_syms);
+ collision_syms = meta_get_symbol_collision(target, patch_syms);
if (collision_syms != NULL) {
log_warn("{%s}: Patch symbol conflicted\n", uuid);
- patch_symbols_free(patch_syms);
- meta_put_symbol_collision(collision_syms);
- return EEXIST;
+ ret = EEXIST;
+ goto out;
}
}
// Alloc memory for patch
- patch_entity_t *patch_entity = calloc(1, sizeof(patch_entity_t));
+ patch_entity = calloc(1, sizeof(patch_entity_t));
if (patch_entity == NULL) {
log_warn("{%s}: Failed to alloc memory\n", uuid);
- patch_symbols_free(patch_syms);
- return ENOMEM;
+ ret = ENOMEM;
+ goto out;
}
strncpy(patch_entity->target_path, target, strnlen(target, PATH_MAX));
@@ -91,17 +141,27 @@ int upatch_load(const char *uuid, const char *target, const char *patch, bool fo
log_normal("patch: %s, patch_path: %s\n", patch, patch_entity->patch_path);
patch_entity->symbols = patch_syms;
- int ret = meta_create_patch(uuid, patch_entity);
+ ret = meta_create_patch(uuid, patch_entity);
if (ret != 0) {
log_warn("{%s}: Failed to create patch entity\n", uuid);
- free(patch_entity);
- patch_symbols_free(patch_syms);
- return ret;
+ goto out;
}
- free(patch_entity);
meta_set_patch_status(uuid, UPATCH_PATCH_STATUS_DEACTIVED);
+out:
+ if (collision_syms != NULL) {
+ meta_put_symbol_collision(collision_syms);
+ }
+ if (patch_syms != NULL) {
+ patch_symbols_free(patch_syms);
+ }
+ if (patch_entity != NULL) {
+ free(patch_entity);
+ }
+ binary_close(&relf);
+ upatch_close(&uelf);
+
return ret;
}
--
2.33.0

View File

@ -12,11 +12,28 @@
############################################
Name: syscare
Version: 1.2.0
Release: 6
Release: 10
Summary: System hot-fix service
License: MulanPSL-2.0 and GPL-2.0-only
URL: https://gitee.com/openeuler/syscare
Source0: %{name}-%{version}.tar.gz
Patch0001: 0001-builder-fix-enabling-multiple-kpatch-may-lead-soft-l.patch
Patch0002: 0002-upatch-fix-upatch-manage-detach-failure-issue.patch
Patch0003: 0003-upatch-remove-upatch-manage-log-file.patch
Patch0004: 0004-upatch-remove-redudant-log-output.patch
Patch0005: 0005-upatch-manage-close-dup-fd.patch
Patch0006: 0006-daemon-check-patch-before-patch-restoration.patch
Patch0007: 0007-upatch-elf-verification.patch
Patch0008: 0008-upatch-check-build-id.patch
Patch0009: 0009-README-add-example-for-kernel-module-patch-build.patch
Patch0010: 0010-daemon-fix-check-build-id-logic.patch
Patch0011: 0011-upatch-diff-fix-a-nullptr-issue.patch
Patch0012: 0012-daemon-fix-rust-1.60-compile-issue.patch
Patch0013: 0013-upatchd-create-config-dir-at-startup.patch
Patch0014: 0014-syscare-move-files-to-working-directory.patch
Patch0015: 0015-upatch-fix-memory-leak.patch
BuildRequires: cmake >= 3.14 make
BuildRequires: rust >= 1.51 cargo >= 1.51
BuildRequires: gcc gcc-c++
@ -177,6 +194,15 @@ depmod > /dev/null 2>&1
################ Change log ################
############################################
%changelog
* Tue Dec 26 2023 ningyu<ningyu9@huawei.com> - 1.2.0-10
- fix memory leak
* Fri Dec 22 2023 ningyu<ningyu9@huawei.com> - 1.2.0-9
- Add Suggests for syscare-build
- Remove log directory
* Tue Dec 12 2023 renoseven<dev@renoseven.net> - 1.2.0-8
- Builder: fix 'enabling multiple kpatch may lead soft-lockup' issue
* Wed Nov 29 2023 renoseven<dev@renoseven.net> - 1.2.0-7
- Fix aarch64 compile issue
* Tue Nov 28 2023 renoseven<dev@renoseven.net> - 1.2.0-6
- Enable debuginfo for rust code
- Sync arguments with old version