diff --git a/0001-upatch-fix-memory-leak.patch b/0001-upatch-fix-memory-leak.patch deleted file mode 100644 index bc21fdca5997086b3e1ab4d0c1a4ed82dec6dc45..0000000000000000000000000000000000000000 --- a/0001-upatch-fix-memory-leak.patch +++ /dev/null @@ -1,362 +0,0 @@ -From 433594d38d6c35c6189af97dfdd0007eb9c114b7 Mon Sep 17 00:00:00 2001 -From: renoseven -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 - diff --git a/generate_package.sh b/generate_package.sh index b9b3c407a8a486c31e502825b1b6969a1a32d64d..07c0d87468c5ab5c98976e9fe90256598fc9b09b 100755 --- a/generate_package.sh +++ b/generate_package.sh @@ -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 diff --git a/syscare-1.2.0.tar.gz b/syscare-1.2.1.tar.gz similarity index 70% rename from syscare-1.2.0.tar.gz rename to syscare-1.2.1.tar.gz index d2f5be22dff5b930928823d3b98e6395b0f36670..616f843d63e0d3623da168d9c2a4b2bce16a9901 100644 Binary files a/syscare-1.2.0.tar.gz and b/syscare-1.2.1.tar.gz differ diff --git a/syscare.spec b/syscare.spec index fca58152c47938602458a33e486883514acccfb4..5b7c1dfce318f7a00c17c4becf226baf503300b4 100644 --- a/syscare.spec +++ b/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: 1 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 - 1.2.1-1 +- update to 1.2.1 * Tue Dec 26 2023 ningyu - 1.2.0-10 - fix memory leak * Fri Dec 22 2023 ningyu - 1.2.0-9