!165 update to 1.2.1
From: @bb-cat Reviewed-by: @snoweay Signed-off-by: @snoweay
This commit is contained in:
commit
eeba71bf90
@ -1,362 +0,0 @@
|
||||
From 433594d38d6c35c6189af97dfdd0007eb9c114b7 Mon Sep 17 00:00:00 2001
|
||||
From: renoseven <dev@renoseven.net>
|
||||
Date: Tue, 26 Dec 2023 08:49:07 +0000
|
||||
Subject: [PATCH] upatch: fix memory leak
|
||||
|
||||
---
|
||||
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 733f6fa..0e09cb2 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 0956f57..62ba907 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 fc1caaf..4e5441f 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 78e25f3..b4e4924 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 85739fe..9a6caa1 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
|
||||
|
||||
@ -19,7 +19,7 @@ echo "Checking out dest branch..."
|
||||
git checkout "$REPO_BRANCH"
|
||||
|
||||
echo "Vendoring dependencies..."
|
||||
cargo vendor --respect-source-config --sync upatch/Cargo.toml
|
||||
cargo vendor --respect-source-config --sync Cargo.toml
|
||||
|
||||
mkdir -p .cargo
|
||||
cat << EOF > .cargo/config.toml
|
||||
|
||||
Binary file not shown.
77
syscare.spec
77
syscare.spec
@ -5,22 +5,18 @@
|
||||
|
||||
%define pkg_kmod %{name}-kmod
|
||||
%define pkg_build %{name}-build
|
||||
%define pkg_build_kmod %{pkg_build}-kmod
|
||||
%define pkg_build_ebpf %{pkg_build}-ebpf
|
||||
|
||||
############################################
|
||||
############ Package syscare ###############
|
||||
############################################
|
||||
Name: syscare
|
||||
Version: 1.2.0
|
||||
Release: 10
|
||||
Version: 1.2.1
|
||||
Release: 0
|
||||
Summary: System hot-fix service
|
||||
License: MulanPSL-2.0 and GPL-2.0-only
|
||||
URL: https://gitee.com/openeuler/syscare
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
|
||||
Patch0001: 0001-upatch-fix-memory-leak.patch
|
||||
|
||||
BuildRequires: cmake >= 3.14 make
|
||||
BuildRequires: rust >= 1.51 cargo >= 1.51
|
||||
BuildRequires: gcc gcc-c++
|
||||
@ -54,9 +50,6 @@ make
|
||||
cd build
|
||||
%make_install
|
||||
|
||||
mkdir -p %{buildroot}/lib/modules/%{kernel_name}/extra/syscare
|
||||
mv -f %{buildroot}/usr/libexec/syscare/upatch_hijacker.ko %{buildroot}/lib/modules/%{kernel_name}/extra/syscare
|
||||
|
||||
############### PostInstall ################
|
||||
%post
|
||||
mkdir -p /usr/lib/syscare/patches
|
||||
@ -107,8 +100,6 @@ fi
|
||||
%package build
|
||||
Summary: Syscare build tools.
|
||||
BuildRequires: elfutils-libelf-devel
|
||||
Suggests: %{pkg_build_kmod}
|
||||
Requires: (%{pkg_build_kmod} >= %{build_version} or %{pkg_build_ebpf} >= %{build_version})
|
||||
Requires: coreutils
|
||||
Requires: patch
|
||||
Requires: kpatch
|
||||
@ -165,70 +156,16 @@ fi
|
||||
%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
|
||||
|
||||
############################################
|
||||
######## Package syscare-build-kmod ########
|
||||
############################################
|
||||
%package build-kmod
|
||||
Summary: Kernel module for syscare patch build tools.
|
||||
BuildRequires: make gcc
|
||||
BuildRequires: kernel-devel
|
||||
Requires: kernel >= %{kernel_version}
|
||||
|
||||
############### Description ################
|
||||
%description build-kmod
|
||||
Syscare build dependency - kernel module.
|
||||
|
||||
############### PostInstall ################
|
||||
%post build-kmod
|
||||
echo "/lib/modules/%{kernel_name}/extra/syscare/upatch_hijacker.ko" | /sbin/weak-modules --add-module --no-initramfs
|
||||
depmod > /dev/null 2>&1
|
||||
|
||||
############### PreUninstall ###############
|
||||
%preun build-kmod
|
||||
# Nothing
|
||||
|
||||
############## PostUninstall ###############
|
||||
%postun build-kmod
|
||||
echo "/lib/modules/%{kernel_name}/extra/syscare/upatch_hijacker.ko" | /sbin/weak-modules --remove-module --no-initramfs
|
||||
depmod > /dev/null 2>&1
|
||||
|
||||
################## Files ###################
|
||||
%files build-kmod
|
||||
%dir /lib/modules/%{kernel_name}/extra/syscare
|
||||
%attr(640,root,root) /lib/modules/%{kernel_name}/extra/syscare/upatch_hijacker.ko
|
||||
|
||||
############################################
|
||||
######## Package syscare-build-ebpf ########
|
||||
############################################
|
||||
%package build-ebpf
|
||||
Summary: eBPF for syscare patch build tools.
|
||||
BuildRequires: make llvm clang bpftool
|
||||
BuildRequires: libbpf libbpf-devel libbpf-static
|
||||
|
||||
############### Description ################
|
||||
%description build-ebpf
|
||||
Syscare build dependency - eBPF.
|
||||
|
||||
############### PostInstall ################
|
||||
%post build-ebpf
|
||||
|
||||
############### PreUninstall ###############
|
||||
%preun build-ebpf
|
||||
# Nothing
|
||||
|
||||
############## PostUninstall ###############
|
||||
%postun build-ebpf
|
||||
# Nothing
|
||||
|
||||
################## Files ###################
|
||||
%files build-ebpf
|
||||
%attr(755,root,root) /usr/libexec/syscare/upatch_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
|
||||
|
||||
############################################
|
||||
################ Change log ################
|
||||
############################################
|
||||
%changelog
|
||||
* Thu Mar 28 2024 ningyu<ningyu9@huawei.com> - 1.2.1-0
|
||||
- update to 1.2.1
|
||||
* Tue Dec 26 2023 ningyu<ningyu9@huawei.com> - 1.2.0-10
|
||||
- fix memory leak
|
||||
* Fri Dec 22 2023 ningyu<ningyu9@huawei.com> - 1.2.0-9
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user