syscare/0002-upatch-fix-upatch-manage-detach-failure-issue.patch
ningyu 5909c8dc30 update to 1.2.0-10
Sync patch
2023-12-28 17:21:44 +08:00

2204 lines
65 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 205d718e13214f49c08c60d291e051dd67f1708a Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Tue, 19 Dec 2023 18:01:48 +0800
Subject: [PATCH 02/15] upatch: fix upatch manage detach failure issue
Signed-off-by: renoseven <dev@renoseven.net>
---
upatch/upatch-manage/arch/aarch64/insn.c | 4 +-
upatch/upatch-manage/arch/aarch64/resolve.c | 16 +-
upatch/upatch-manage/arch/x86_64/resolve.c | 14 +-
.../upatch-manage/ebpf/upatch-manager.bpf.c | 2 +-
upatch/upatch-manage/ebpf/upatch-manager.c | 2 +-
upatch/upatch-manage/upatch-elf.c | 312 +++++++++---------
upatch/upatch-manage/upatch-elf.h | 2 +
upatch/upatch-manage/upatch-manage.c | 99 +++---
upatch/upatch-manage/upatch-patch.c | 198 +++++------
upatch/upatch-manage/upatch-process.c | 300 +++++++++--------
upatch/upatch-manage/upatch-process.h | 6 +-
upatch/upatch-manage/upatch-ptrace.c | 114 ++++---
upatch/upatch-manage/upatch-relocation.c | 3 +-
upatch/upatch-manage/upatch-resolve.c | 31 +-
14 files changed, 545 insertions(+), 558 deletions(-)
diff --git a/upatch/upatch-manage/arch/aarch64/insn.c b/upatch/upatch-manage/arch/aarch64/insn.c
index 02faa3e..0a0004f 100644
--- a/upatch/upatch-manage/arch/aarch64/insn.c
+++ b/upatch/upatch-manage/arch/aarch64/insn.c
@@ -110,7 +110,7 @@ u64 extract_insn_imm(s64 sval, int len, int lsb)
imm_mask = (BIT(lsb + len) - 1) >> lsb;
imm = imm & imm_mask;
- log_debug("upatch: extract imm, X=0x%lx, X[%d:%d]=0x%lx \n", sval,
+ log_debug("upatch: extract imm, X=0x%lx, X[%d:%d]=0x%lx\n", sval,
(len + lsb - 1), lsb, imm);
return imm;
}
@@ -124,7 +124,7 @@ u32 insert_insn_imm(enum aarch64_insn_imm_type imm_type, void *place, u64 imm)
log_debug(
"upatch: insert imm, P=0x%lx, insn=0x%x, imm_type=%d, imm=0x%lx, "
- "new_insn=0x%x \n",
+ "new_insn=0x%x\n",
(u64)place, insn, imm_type, imm, new_insn);
return new_insn;
}
diff --git a/upatch/upatch-manage/arch/aarch64/resolve.c b/upatch/upatch-manage/arch/aarch64/resolve.c
index a3ea30f..2c9c882 100644
--- a/upatch/upatch-manage/arch/aarch64/resolve.c
+++ b/upatch/upatch-manage/arch/aarch64/resolve.c
@@ -40,7 +40,7 @@ static unsigned long setup_jmp_table(struct upatch_elf *uelf,
uelf->core_layout.kbase + uelf->jmp_offs;
unsigned int index = uelf->jmp_cur_entry;
if (index >= uelf->jmp_max_entry) {
- log_error("jmp table overflow \n");
+ log_error("jmp table overflow\n");
return 0;
}
@@ -62,7 +62,7 @@ static unsigned long setup_got_table(struct upatch_elf *uelf,
unsigned int index = uelf->jmp_cur_entry;
if (index >= uelf->jmp_max_entry) {
- log_error("got table overflow \n");
+ log_error("got table overflow\n");
return 0;
}
@@ -84,14 +84,14 @@ unsigned long insert_plt_table(struct upatch_elf *uelf, struct object_file *obj,
if (upatch_process_mem_read(obj->proc, addr, &jmp_addr,
sizeof(jmp_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
if (r_type == R_AARCH64_TLSDESC &&
upatch_process_mem_read(obj->proc, addr + sizeof(unsigned long),
&tls_addr, sizeof(tls_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
@@ -100,7 +100,7 @@ unsigned long insert_plt_table(struct upatch_elf *uelf, struct object_file *obj,
else
elf_addr = setup_jmp_table(uelf, jmp_addr, (unsigned long)addr);
- log_debug("0x%lx: jmp_addr=0x%lx, tls_addr=0x%lx \n", elf_addr,
+ log_debug("0x%lx: jmp_addr=0x%lx, tls_addr=0x%lx\n", elf_addr,
jmp_addr, tls_addr);
out:
@@ -116,20 +116,20 @@ unsigned long insert_got_table(struct upatch_elf *uelf, struct object_file *obj,
if (upatch_process_mem_read(obj->proc, addr, &jmp_addr,
sizeof(jmp_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
if (r_type == R_AARCH64_TLSDESC &&
upatch_process_mem_read(obj->proc, addr + sizeof(unsigned long),
&tls_addr, sizeof(tls_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
elf_addr = setup_got_table(uelf, jmp_addr, tls_addr);
- log_debug("0x%lx: jmp_addr=0x%lx, tls_addr=0x%lx \n", elf_addr,
+ log_debug("0x%lx: jmp_addr=0x%lx, tls_addr=0x%lx\n", elf_addr,
jmp_addr, tls_addr);
out:
diff --git a/upatch/upatch-manage/arch/x86_64/resolve.c b/upatch/upatch-manage/arch/x86_64/resolve.c
index 9d3e539..e05d670 100644
--- a/upatch/upatch-manage/arch/x86_64/resolve.c
+++ b/upatch/upatch-manage/arch/x86_64/resolve.c
@@ -32,7 +32,7 @@ static unsigned long setup_jmp_table(struct upatch_elf *uelf,
uelf->core_layout.kbase + uelf->jmp_offs;
unsigned int index = uelf->jmp_cur_entry;
if (index >= uelf->jmp_max_entry) {
- log_error("jmp table overflow \n");
+ log_error("jmp table overflow\n");
return 0;
}
@@ -57,7 +57,7 @@ static unsigned long setup_got_table(struct upatch_elf *uelf,
uelf->core_layout.kbase + uelf->jmp_offs;
unsigned int index = uelf->jmp_cur_entry;
if (index >= uelf->jmp_max_entry) {
- log_error("got table overflow \n");
+ log_error("got table overflow\n");
return 0;
}
@@ -76,13 +76,13 @@ unsigned long insert_plt_table(struct upatch_elf *uelf, struct object_file *obj,
if (upatch_process_mem_read(obj->proc, addr, &jmp_addr,
sizeof(jmp_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
elf_addr = setup_jmp_table(uelf, jmp_addr);
- log_debug("0x%lx: jmp_addr=0x%lx \n", elf_addr, jmp_addr);
+ log_debug("0x%lx: jmp_addr=0x%lx\n", elf_addr, jmp_addr);
out:
return elf_addr;
@@ -97,7 +97,7 @@ unsigned long insert_got_table(struct upatch_elf *uelf, struct object_file *obj,
if (upatch_process_mem_read(obj->proc, addr, &jmp_addr,
sizeof(jmp_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
@@ -109,13 +109,13 @@ unsigned long insert_got_table(struct upatch_elf *uelf, struct object_file *obj,
if (r_type == R_X86_64_DTPMOD64 &&
upatch_process_mem_read(obj->proc, addr + sizeof(unsigned long),
&tls_addr, sizeof(tls_addr))) {
- log_error("copy address failed \n");
+ log_error("copy address failed\n");
goto out;
}
elf_addr = setup_got_table(uelf, jmp_addr, tls_addr);
- log_debug("0x%lx: jmp_addr=0x%lx \n", elf_addr, jmp_addr);
+ log_debug("0x%lx: jmp_addr=0x%lx\n", elf_addr, jmp_addr);
out:
return elf_addr;
diff --git a/upatch/upatch-manage/ebpf/upatch-manager.bpf.c b/upatch/upatch-manage/ebpf/upatch-manager.bpf.c
index d91a446..eb9282c 100644
--- a/upatch/upatch-manage/ebpf/upatch-manager.bpf.c
+++ b/upatch/upatch-manage/ebpf/upatch-manager.bpf.c
@@ -36,6 +36,6 @@ int BPF_KPROBE(install_breakpoint, struct uprobe *uprobe, struct mm_struct *mm,
ep.ino = BPF_CORE_READ(uprobe, inode, i_ino);
ep.pid = BPF_CORE_READ(mm, owner, pid);
bpf_map_update_elem(&elf_process_maps, &ep, &initial_entry, BPF_ANY);
- bpf_printk("ino %lu works for pid %d in addr 0x%lx \n", ep.ino, ep.pid, vaddr);
+ bpf_printk("ino %lu works for pid %d in addr 0x%lx\n", ep.ino, ep.pid, vaddr);
return 0;
}
\ No newline at end of file
diff --git a/upatch/upatch-manage/ebpf/upatch-manager.c b/upatch/upatch-manage/ebpf/upatch-manager.c
index f573d72..0215464 100644
--- a/upatch/upatch-manage/ebpf/upatch-manager.c
+++ b/upatch/upatch-manage/ebpf/upatch-manager.c
@@ -58,7 +58,7 @@ int main(int argc, char **argv)
skel->progs.install_breakpoint, false, "install_breakpoint");
if (!skel->links.install_breakpoint) {
err = -errno;
- fprintf(stderr, "Failed to attach kprobe for install_breakpoint: %d \n", err);
+ fprintf(stderr, "Failed to attach kprobe for install_breakpoint: %d\n", err);
goto cleanup;
}
diff --git a/upatch/upatch-manage/upatch-elf.c b/upatch/upatch-manage/upatch-elf.c
index edcafe0..2bd3175 100644
--- a/upatch/upatch-manage/upatch-elf.c
+++ b/upatch/upatch-manage/upatch-elf.c
@@ -21,204 +21,190 @@
static int read_from_offset(int fd, void **buf, int len, off_t offset)
{
- int ret = -1;
- size_t size;
+ *buf = malloc(len);
+ if (*buf == NULL) {
+ return -errno;
+ }
- *buf = malloc(len);
- if (*buf == NULL) {
- printf("malloc failed \n");
- goto out;
- }
-
- size = pread(fd, *buf, len, offset);
- if (size == -1) {
- ret = -errno;
- printf("read file failed - %d \n", -ret);
- goto out;
- }
+ int size = pread(fd, *buf, len, offset);
+ if (size == -1) {
+ return -errno;
+ }
- ret = 0;
-out:
- return ret;
+ return 0;
}
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)
- ERROR("open %s failed with errno %d \n", name, errno);
-
- ret = stat(name, &st);
- if (ret)
- ERROR("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_error("no %s found \n", BUILD_ID_NAME);
- goto out;
- }
+ 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;
+
+ 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;
- log_error("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)
{
- int ret = 0, i;
- char *sec_name;
-
- memset(uelf, 0, sizeof(struct upatch_elf));
-
- ret = open_elf(&uelf->info, name);
- if (ret)
- goto out;
-
- for (i = 1; i < uelf->info.hdr->e_shnum; ++i) {
- sec_name = uelf->info.shstrtab + uelf->info.shdrs[i].sh_name;
- if (uelf->info.shdrs[i].sh_type == SHT_SYMTAB) {
- uelf->num_syms =
- uelf->info.shdrs[i].sh_size / sizeof(GElf_Sym);
- uelf->index.sym = i;
- uelf->index.str = uelf->info.shdrs[i].sh_link;
- uelf->strtab =
- (char *)uelf->info.hdr +
- uelf->info.shdrs[uelf->info.shdrs[i].sh_link]
- .sh_offset;
- } else if (streql(sec_name, UPATCH_FUNC_NAME)) {
- uelf->index.upatch_funcs = i;
- }
- }
-
- ret = 0;
-
-out:
- return ret;
+ int ret = open_elf(&uelf->info, name);
+ if (ret) {
+ log_error("Failed to open elf '%s', ret=%d\n", name, ret);
+ return ret;
+ }
+
+ for (int i = 1; i < uelf->info.hdr->e_shnum; ++i) {
+ char *sec_name = uelf->info.shstrtab + uelf->info.shdrs[i].sh_name;
+ if (uelf->info.shdrs[i].sh_type == SHT_SYMTAB) {
+ uelf->num_syms = uelf->info.shdrs[i].sh_size / sizeof(GElf_Sym);
+ uelf->index.sym = i;
+ uelf->index.str = uelf->info.shdrs[i].sh_link;
+ uelf->strtab = (char *)uelf->info.hdr +
+ uelf->info.shdrs[uelf->info.shdrs[i].sh_link].sh_offset;
+ } else if (streql(sec_name, UPATCH_FUNC_NAME)) {
+ uelf->index.upatch_funcs = i;
+ }
+ }
+
+ return 0;
}
int binary_init(struct running_elf *relf, const char *name)
{
- int ret = 0, i;
- char *sec_name;
-
- memset(relf, 0, sizeof(struct running_elf));
-
- ret = open_elf(&relf->info, name);
- if (ret)
- goto out;
-
- relf->phdrs = (void *)relf->info.hdr + relf->info.hdr->e_phoff;
-
- for (i = 1; i < relf->info.hdr->e_shnum; i++) {
- sec_name = relf->info.shstrtab + relf->info.shdrs[i].sh_name;
- if (relf->info.shdrs[i].sh_type == SHT_SYMTAB) {
- relf->num_syms =
- relf->info.shdrs[i].sh_size / sizeof(GElf_Sym);
- relf->index.sym = i;
- relf->index.str = relf->info.shdrs[i].sh_link;
- relf->strtab =
- (char *)relf->info.hdr +
- relf->info.shdrs[relf->info.shdrs[i].sh_link]
- .sh_offset;
- } else if (relf->info.shdrs[i].sh_type == SHT_DYNSYM) {
- relf->index.dynsym = i;
- relf->index.dynstr = relf->info.shdrs[i].sh_link;
- relf->dynstrtab =
- (char *)relf->info.hdr +
- relf->info.shdrs[relf->info.shdrs[i].sh_link]
- .sh_offset;
- log_debug("found dynsym with %d \n", i);
- } else if (relf->info.shdrs[i].sh_type == SHT_DYNAMIC) {
- /* Currently, we don't utilize it */
- } else if (streql(sec_name, PLT_RELA_NAME) &&
- relf->info.shdrs[i].sh_type == SHT_RELA) {
- relf->index.rela_plt = i;
- log_debug("found %s with %d \n", PLT_RELA_NAME, i);
- } else if (streql(sec_name, GOT_RELA_NAME) &&
- relf->info.shdrs[i].sh_type == SHT_RELA) {
- relf->index.rela_dyn = i;
- log_debug("found %s with %d \n", GOT_RELA_NAME, i);
- }
- }
-
- for (i = 0; i < relf->info.hdr->e_phnum; i++) {
- if (relf->phdrs[i].p_type == PT_TLS) {
- relf->tls_size = relf->phdrs[i].p_memsz;
- relf->tls_align = relf->phdrs[i].p_align;
- log_debug("found TLS size = %ld, memsz = %ld \n",
- relf->tls_size, relf->tls_align);
- break;
- }
- }
-
- ret = 0;
-
-out:
- return ret;
+ int ret = open_elf(&relf->info, name);
+ if (ret) {
+ log_error("Failed to open elf '%s', ret=%d\n", name, ret);
+ return ret;
+ }
+
+ for (int i = 1; i < relf->info.hdr->e_shnum; i++) {
+ char *sec_name = relf->info.shstrtab + relf->info.shdrs[i].sh_name;
+ if (relf->info.shdrs[i].sh_type == SHT_SYMTAB) {
+ log_debug("Found section '%s', idx=%d\n", SYMTAB_NAME, i);
+ relf->num_syms = relf->info.shdrs[i].sh_size / sizeof(GElf_Sym);
+ relf->index.sym = i;
+ relf->index.str = relf->info.shdrs[i].sh_link;
+ relf->strtab = (char *)relf->info.hdr +
+ relf->info.shdrs[relf->info.shdrs[i].sh_link].sh_offset;
+ } else if (relf->info.shdrs[i].sh_type == SHT_DYNSYM) {
+ log_debug("Found section '%s', idx=%d\n", DYNSYM_NAME, i);
+ relf->index.dynsym = i;
+ relf->index.dynstr = relf->info.shdrs[i].sh_link;
+ 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 */
+ } 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);
+ relf->index.rela_plt = i;
+ } else if (streql(sec_name, GOT_RELA_NAME) &&
+ relf->info.shdrs[i].sh_type == SHT_RELA) {
+ log_debug("Found section '%s' idx=%d\n", GOT_RELA_NAME, i);
+ relf->index.rela_dyn = i;
+ }
+ }
+
+ relf->phdrs = (void *)relf->info.hdr + relf->info.hdr->e_phoff;
+ for (int i = 0; i < relf->info.hdr->e_phnum; i++) {
+ if (relf->phdrs[i].p_type == PT_TLS) {
+ relf->tls_size = relf->phdrs[i].p_memsz;
+ relf->tls_align = relf->phdrs[i].p_align;
+ log_debug("Found TLS size = %ld, align = %ld\n", relf->tls_size, relf->tls_align);
+ break;
+ }
+ }
+
+ return 0;
}
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)
{
- // TODO: free relf
- if (relf->info.patch_buff)
- free(relf->info.patch_buff);
+ // TODO: free relf
+ if (relf->info.patch_buff) {
+ free(relf->info.patch_buff);
+ }
}
void upatch_close(struct upatch_elf *uelf)
{
- // TODO: free uelf
- if (uelf->info.patch_buff)
- free(uelf->info.patch_buff);
+ // TODO: free uelf
+ if (uelf->info.patch_buff) {
+ free(uelf->info.patch_buff);
+ }
- if (uelf->core_layout.kbase)
- free(uelf->core_layout.kbase);
+ if (uelf->core_layout.kbase) {
+ free(uelf->core_layout.kbase);
+ }
}
bool is_upatch_section(const char *name)
{
- return !strncmp(name, ".upatch.", strlen(".upatch."));
+ return !strncmp(name, ".upatch.", strlen(".upatch."));
}
bool is_note_section(GElf_Word type)
{
- return type == SHT_NOTE;
+ return type == SHT_NOTE;
}
diff --git a/upatch/upatch-manage/upatch-elf.h b/upatch/upatch-manage/upatch-elf.h
index 438b573..b4d9b28 100644
--- a/upatch/upatch-manage/upatch-elf.h
+++ b/upatch/upatch-manage/upatch-elf.h
@@ -17,6 +17,8 @@
#include "list.h"
+#define SYMTAB_NAME ".symtab"
+#define DYNSYM_NAME ".dynsym"
#define GOT_RELA_NAME ".rela.dyn"
#define PLT_RELA_NAME ".rela.plt"
#define BUILD_ID_NAME ".note.gnu.build-id"
diff --git a/upatch/upatch-manage/upatch-manage.c b/upatch/upatch-manage/upatch-manage.c
index f827794..b36ff0d 100644
--- a/upatch/upatch-manage/upatch-manage.c
+++ b/upatch/upatch-manage/upatch-manage.c
@@ -124,55 +124,32 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
static struct argp argp = { options, parse_opt, args_doc, program_doc };
-static void show_program_info(struct arguments *arguments)
-{
- log_debug("pid: %d\n", arguments->pid);
- log_debug("upatch object: %s\n", arguments->upatch);
- log_debug("binary object: %s\n", arguments->binary);
- log_debug("uuid object: %s\n", arguments->uuid);
-}
+FILE *upatch_manage_log_fd = NULL;
int patch_upatch(const char *uuid, const char *binary_path, const char *upatch_path, int pid)
{
- int ret;
struct upatch_elf uelf;
struct running_elf relf;
memset(&uelf, 0, sizeof(struct upatch_elf));
memset(&relf, 0, sizeof(struct running_elf));
- ret = upatch_init(&uelf, upatch_path);
- if (ret) {
- log_error("upatch_init failed %d \n", ret);
- goto out;
- }
-
- /*ret = binary_init(&relf, binary_path);
+ int ret = upatch_init(&uelf, upatch_path);
if (ret) {
- log_error("binary_init failed %d \n", ret);
+ log_error("Failed to initialize patch, ret=%d\n", ret);
goto out;
}
- uelf.relf = &relf;
-*/
- // ret = check_build_id(&uelf.info, &relf.info);
- // if (ret) {
- // log_error("check build id failed %d \n", ret);
- // goto out;
- // }
-
ret = process_patch(pid, &uelf, &relf, uuid, binary_path);
if (ret) {
- log_error("process patch failed %d \n", ret);
+ log_error("Failed to patch process, pid=%d ret=%d\n", pid, ret);
goto out;
}
+ log_normal("SUCCESS\n");
out:
upatch_close(&uelf);
binary_close(&relf);
- if (ret)
- log_normal("FAIL\n");
- else
- log_normal("SUCCESS\n");
+
return ret;
}
@@ -182,66 +159,64 @@ int unpatch_upatch(const char *uuid, const char *binary_path, const char *upatch
ret = process_unpatch(pid, uuid);
if (ret) {
- log_error("process patch failed %d \n", ret);
- goto out;
+ log_error("Failed to unpatch process, pid=%d, ret=%d\n", pid, ret);
+ return ret;
}
+ log_normal("SUCCESS\n");
-out:
- if (ret)
- log_normal("FAIL\n");
- else
- log_normal("SUCCESS\n");
- return ret;
+ return 0;
}
int info_upatch(const char *binary_path, const char *upatch_path, int pid)
{
- int ret = 0;
-
- ret = process_info(pid);
- if (ret) {
- log_error("process patch failed %d \n", ret);
- goto out;
+ int ret = process_info(pid);
+ if (ret != 0) {
+ log_error("Failed to get patch info, pid=%d, ret=%d\n", pid, ret);
+ return ret;
}
+ log_normal("SUCCESS\n");
-out:
- return ret;
+ return 0;
}
-FILE *upatch_manage_log_fd = NULL;
int main(int argc, char *argv[])
{
- struct arguments arguments;
+ struct arguments args;
int ret;
- upatch_manage_log_fd = fopen("/tmp/upatch-manage.log", "w");
- if (upatch_manage_log_fd < 0)
+ upatch_manage_log_fd = fopen("/tmp/upatch-manage.log", "w");
+ if (upatch_manage_log_fd < 0) {
return -1;
- memset(&arguments, 0, sizeof(arguments));
- argp_parse(&argp, argc, argv, 0, NULL, &arguments);
- if (arguments.verbose)
+ }
+
+ memset(&args, 0, sizeof(struct arguments));
+ argp_parse(&argp, argc, argv, 0, NULL, &args);
+ if (args.verbose) {
loglevel = DEBUG;
+ }
+
+ logprefix = basename(args.upatch);
+ log_debug("PID: %d\n", args.pid);
+ log_debug("UUID: %s\n", args.uuid);
+ log_debug("Patch: %s\n", args.upatch);
+ log_debug("Binary: %s\n", args.binary);
- logprefix = basename(arguments.upatch);
- show_program_info(&arguments);
- switch (arguments.cmd) {
+ switch (args.cmd) {
case PATCH:
- ret = patch_upatch(arguments.uuid, arguments.binary, arguments.upatch,
- arguments.pid);
+ ret = patch_upatch(args.uuid, args.binary, args.upatch, args.pid);
break;
case UNPATCH:
- ret = unpatch_upatch(arguments.uuid, arguments.binary, arguments.upatch,
- arguments.pid);
+ ret = unpatch_upatch(args.uuid, args.binary, args.upatch, args.pid);
break;
case INFO:
- ret = info_upatch(arguments.binary, arguments.upatch,
- arguments.pid);
+ ret = info_upatch(args.binary, args.upatch, args.pid);
break;
default:
- ERROR("unknown command");
+ ERROR("Unknown command");
ret = EINVAL;
break;
}
+
fclose(upatch_manage_log_fd);
return abs(ret);
}
diff --git a/upatch/upatch-manage/upatch-patch.c b/upatch/upatch-manage/upatch-patch.c
index bdb9631..762641c 100644
--- a/upatch/upatch-manage/upatch-patch.c
+++ b/upatch/upatch-manage/upatch-patch.c
@@ -18,6 +18,7 @@
#include "log.h"
#include "upatch-common.h"
#include "upatch-patch.h"
+#include "upatch-process.h"
#include "upatch-ptrace.h"
#include "upatch-relocation.h"
#include "upatch-resolve.h"
@@ -101,7 +102,7 @@ static int rewrite_section_headers(struct upatch_elf *uelf)
/* Mark all sections sh_addr with their address in the
temporary image. */
shdr->sh_addr = (size_t)uelf->info.hdr + shdr->sh_offset;
- log_debug("section %s at 0x%lx \n",
+ log_debug("section %s at 0x%lx\n",
uelf->info.shstrtab + shdr->sh_name, shdr->sh_addr);
}
@@ -165,7 +166,7 @@ static void layout_sections(struct upatch_elf *uelf)
for (i = 0; i < uelf->info.hdr->e_shnum; i++)
uelf->info.shdrs[i].sh_entsize = ~0UL;
- log_debug("upatch section allocation order: \n");
+ log_debug("upatch section allocation order:\n");
for (m = 0; m < ARRAY_SIZE(masks); ++m) {
for (i = 0; i < uelf->info.hdr->e_shnum; ++i) {
GElf_Shdr *s = &uelf->info.shdrs[i];
@@ -279,18 +280,17 @@ static void *upatch_alloc(struct object_file *obj, size_t sz)
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1,
0);
if (addr == 0) {
- log_error("remote alloc memory for patch failed\n");
+ log_error("Failed to alloc remote patch memory\n");
return NULL;
}
- log_debug("allocated 0x%lx bytes at 0x%lx for '%s' patch\n", sz, addr,
- obj->name);
+ log_debug("Allocated 0x%lx bytes at 0x%lx of '%s'\n", sz, addr, obj->name);
// log_debug("Marking this space as busy\n");
ret = vm_hole_split(hole, addr, addr + sz);
if (ret) {
// TODO: clear
- log_error("vm_hole_split failed\n");
+ log_error("Failed to split vm hole\n");
return NULL;
}
@@ -300,10 +300,9 @@ static void *upatch_alloc(struct object_file *obj, size_t sz)
static void __upatch_memfree(struct object_file *obj, void *base,
unsigned int size)
{
- log_debug("munmap upatch memory at: %p\n", base);
- if (upatch_munmap_remote(proc2pctx(obj->proc), (unsigned long)base,
- size)) {
- log_error("Failed to munmap upatch memory at: %p\n", base);
+ log_debug("Free patch memory %p\n", base);
+ if (upatch_munmap_remote(proc2pctx(obj->proc), (unsigned long)base, size)) {
+ log_error("Failed to free patch memory %p\n", base);
}
}
@@ -313,8 +312,7 @@ static int __alloc_memory(struct object_file *obj_file,
/* Do the allocs. */
layout->base = upatch_alloc(obj_file, layout->size);
if (!layout->base) {
- log_error("alloc upatch core_layout memory failed: %p \n",
- layout->base);
+ log_error("Failed to alloc patch core layout %p\n", layout->base);
return -ENOMEM;
}
@@ -336,25 +334,28 @@ static int alloc_memory(struct upatch_elf *uelf, struct object_file *obj)
/* Do the allocs. */
ret = __alloc_memory(obj, &uelf->core_layout);
if (ret) {
- log_error("alloc upatch module memory failed: %d \n", ret);
+ log_error("Failed to alloc patch memory, ret=%d\n", ret);
return ret;
}
/* Transfer each section which specifies SHF_ALLOC */
- log_debug("final section addresses:\n");
+ log_debug("Final section addresses:\n");
for (i = 0; i < uelf->info.hdr->e_shnum; i++) {
void *kdest;
void *dest;
GElf_Shdr *shdr = &uelf->info.shdrs[i];
- if (!(shdr->sh_flags & SHF_ALLOC))
+ if (!(shdr->sh_flags & SHF_ALLOC)) {
continue;
+ }
kdest = uelf->core_layout.kbase + shdr->sh_entsize;
dest = uelf->core_layout.base + shdr->sh_entsize;
- if (shdr->sh_type != SHT_NOBITS)
+ if (shdr->sh_type != SHT_NOBITS) {
memcpy(kdest, (void *)shdr->sh_addr, shdr->sh_size);
+ }
+
shdr->sh_addr = (unsigned long)kdest;
/* overuse this attr to record user address */
shdr->sh_addralign = (unsigned long)dest;
@@ -369,7 +370,7 @@ static int post_memory(struct upatch_elf *uelf, struct object_file *obj)
{
int ret = 0;
- log_debug("post kbase %lx(%x) to base %lx\n",
+ log_debug("Post kbase %lx(%x) to base %lx\n",
(unsigned long)uelf->core_layout.kbase,
uelf->core_layout.size,
(unsigned long)uelf->core_layout.base);
@@ -377,7 +378,7 @@ static int post_memory(struct upatch_elf *uelf, struct object_file *obj)
(unsigned long)uelf->core_layout.base,
uelf->core_layout.size);
if (ret) {
- log_error("can't move kbase to base - %d\n", ret);
+ log_error("Failed to move kbase to base, ret=%d\n", ret);
goto out;
}
@@ -404,7 +405,7 @@ static int complete_info(struct upatch_elf *uelf, struct object_file *obj, const
sizeof(struct upatch_patch_func);
memcpy(uinfo->id, uuid, strlen(uuid));
- log_debug("change insn:\n");
+ log_debug("Changed insn:\n");
for (i = 0; i < uinfo->changed_func_num; ++i) {
struct upatch_info_func *upatch_func =
(void *)uelf->core_layout.kbase +
@@ -440,26 +441,21 @@ static int unapply_patch(struct object_file *obj,
struct upatch_info_func *funcs,
unsigned int changed_func_num)
{
- int ret = 0, i;
-
- log_debug("change insn:\n");
- for (i = 0; i < changed_func_num; ++i) {
+ log_debug("Changed insn:\n");
+ for (int i = 0; i < changed_func_num; ++i) {
log_debug("\t0x%lx(0x%lx -> 0x%lx)\n", funcs[i].old_addr,
funcs[i].new_insn, funcs[i].old_insn[0]);
- ret = upatch_process_mem_write(obj->proc, &funcs[i].old_insn,
- (unsigned long)funcs[i].old_addr,
- get_origin_insn_len());
+ int ret = upatch_process_mem_write(obj->proc, &funcs[i].old_insn,
+ (unsigned long)funcs[i].old_addr, get_origin_insn_len());
if (ret) {
- log_error("can't write old insn at 0x%lx - %d\n",
- funcs[i].old_addr, ret);
- goto out;
+ log_error("Failed to write old insn at 0x%lx, ret=%d\n",
+ funcs[i].old_addr, ret);
+ return ret;
}
}
-
-out:
- return ret;
+ return 0;
}
static int apply_patch(struct upatch_elf *uelf, struct object_file *obj)
@@ -475,40 +471,37 @@ static int apply_patch(struct upatch_elf *uelf, struct object_file *obj)
sizeof(struct upatch_info) +
i * sizeof(struct upatch_info_func);
- // write jumper insn to first 8bytes
- ret = upatch_process_mem_write(
- obj->proc, &upatch_func->new_insn,
- (unsigned long)upatch_func->old_addr,
- get_upatch_insn_len());
+ // write jumper insn to first 8 bytes
+ ret = upatch_process_mem_write(obj->proc, &upatch_func->new_insn,
+ (unsigned long)upatch_func->old_addr, get_upatch_insn_len());
if (ret) {
log_error(
- "can't ptrace upatch func at 0x%lx(0x%lx) - %d\n",
+ "Failed to ptrace upatch func at 0x%lx(0x%lx) - %d\n",
upatch_func->old_addr, upatch_func->new_insn,
ret);
goto out;
}
- // write 64bit new addr to second 8bytes
- ret = upatch_process_mem_write(
- obj->proc, &upatch_func->new_addr,
+ // write 64bit new addr to second 8 bytes
+ ret = upatch_process_mem_write(obj->proc, &upatch_func->new_addr,
(unsigned long)upatch_func->old_addr + get_upatch_insn_len(),
get_upatch_addr_len());
if (ret) {
- log_error(
- "can't ptrace upatch func at 0x%lx(0x%lx) - %d\n",
- upatch_func->old_addr + get_upatch_insn_len(),
+ log_error(
+ "Failed to ptrace upatch func at 0x%lx(0x%lx) - %d\n",
+ upatch_func->old_addr + get_upatch_insn_len(),
upatch_func->new_addr,
- ret);
- goto out;
- }
+ ret);
+ goto out;
+ }
}
out:
if (ret) {
unapply_patch(obj,
- (void *)uelf->core_layout.kbase +
- uelf->core_layout.info_size +
- sizeof(struct upatch_info),
- i);
+ (void *)uelf->core_layout.kbase +
+ uelf->core_layout.info_size +
+ sizeof(struct upatch_info),
+ i);
}
return ret;
}
@@ -523,8 +516,7 @@ static int upatch_mprotect(struct upatch_elf *uelf, struct object_file *obj)
(unsigned long)uelf->core_layout.base,
uelf->core_layout.text_size, PROT_READ | PROT_EXEC);
if (ret < 0) {
- log_error(
- "Failed to change upatch text protection to r-x");
+ log_error("Failed to change upatch text protection to r-x");
return ret;
}
}
@@ -532,13 +524,11 @@ static int upatch_mprotect(struct upatch_elf *uelf, struct object_file *obj)
if (uelf->core_layout.ro_size > uelf->core_layout.text_size) {
ret = upatch_mprotect_remote(
proc2pctx(obj->proc),
- (unsigned long)uelf->core_layout.base +
- uelf->core_layout.text_size,
+ (unsigned long)uelf->core_layout.base + uelf->core_layout.text_size,
uelf->core_layout.ro_size - uelf->core_layout.text_size,
PROT_READ);
if (ret < 0) {
- log_error(
- "Failed to change upatch ro protection to r--");
+ log_error("Failed to change upatch ro protection to r--");
return ret;
}
}
@@ -546,14 +536,11 @@ static int upatch_mprotect(struct upatch_elf *uelf, struct object_file *obj)
if (uelf->core_layout.ro_after_init_size > uelf->core_layout.ro_size) {
ret = upatch_mprotect_remote(
proc2pctx(obj->proc),
- (unsigned long)uelf->core_layout.base +
- uelf->core_layout.ro_size,
- uelf->core_layout.ro_after_init_size -
- uelf->core_layout.ro_size,
+ (unsigned long)uelf->core_layout.base + uelf->core_layout.ro_size,
+ uelf->core_layout.ro_after_init_size - uelf->core_layout.ro_size,
PROT_READ);
if (ret < 0) {
- log_error(
- "Failed to change upatch ro init protection to r--");
+ log_error("Failed to change upatch ro init protection to r--");
return ret;
}
}
@@ -562,14 +549,11 @@ static int upatch_mprotect(struct upatch_elf *uelf, struct object_file *obj)
uelf->core_layout.ro_after_init_size) {
ret = upatch_mprotect_remote(
proc2pctx(obj->proc),
- (unsigned long)uelf->core_layout.base +
- uelf->core_layout.ro_after_init_size,
- uelf->core_layout.info_size -
- uelf->core_layout.ro_after_init_size,
+ (unsigned long)uelf->core_layout.base + uelf->core_layout.ro_after_init_size,
+ uelf->core_layout.info_size - uelf->core_layout.ro_after_init_size,
PROT_READ | PROT_WRITE);
if (ret < 0) {
- log_error(
- "Failed to change upatch rw protection to rw-");
+ log_error("Failed to change upatch rw protection to rw-");
return ret;
}
}
@@ -577,13 +561,11 @@ static int upatch_mprotect(struct upatch_elf *uelf, struct object_file *obj)
if (uelf->core_layout.size > uelf->core_layout.info_size) {
ret = upatch_mprotect_remote(
proc2pctx(obj->proc),
- (unsigned long)uelf->core_layout.base +
- uelf->core_layout.info_size,
+ (unsigned long)uelf->core_layout.base + uelf->core_layout.info_size,
uelf->core_layout.size - uelf->core_layout.info_size,
PROT_READ);
if (ret < 0) {
- log_error(
- "Failed to change upatch info protection to r--");
+ log_error("Failed to change upatch info protection to r--");
return ret;
}
}
@@ -628,9 +610,9 @@ static int upatch_apply_patches(struct upatch_process *proc,
layout_symtab(uelf);
layout_upatch_info(uelf);
- log_debug("calculate core_layout = %x \n", uelf->core_layout.size);
+ log_debug("calculate core layout = %x\n", uelf->core_layout.size);
log_debug(
- "core_layout: text_size = %x, ro_size = %x, ro_after_init_size = "
+ "Core layout: text_size = %x, ro_size = %x, ro_after_init_size = "
"%x, info = %x, size = %x\n",
uelf->core_layout.text_size, uelf->core_layout.ro_size,
uelf->core_layout.ro_after_init_size,
@@ -641,35 +623,42 @@ static int upatch_apply_patches(struct upatch_process *proc,
* Otherwise we can't use 32-bit jumps.
*/
ret = alloc_memory(uelf, obj);
- if (ret)
+ if (ret) {
goto free;
+ }
ret = upatch_mprotect(uelf, obj);
- if (ret)
+ if (ret) {
goto free;
+ }
/* Fix up syms, so that st_value is a pointer to location. */
ret = simplify_symbols(uelf, obj);
- if (ret)
+ if (ret) {
goto free;
+ }
/* upatch new address will be updated */
ret = apply_relocations(uelf);
- if (ret)
+ if (ret) {
goto free;
+ }
/* upatch upatch info */
ret = complete_info(uelf, obj, uuid);
- if (ret)
+ if (ret) {
goto free;
+ }
ret = post_memory(uelf, obj);
- if (ret)
+ if (ret) {
goto free;
+ }
ret = apply_patch(uelf, obj);
- if (ret)
+ if (ret) {
goto free;
+ }
ret = 0;
goto out;
@@ -686,12 +675,14 @@ int upatch_process_uuid_exist(struct upatch_process *proc, const char *uuid)
struct object_file *obj;
struct object_patch *patch;
list_for_each_entry(obj, &proc->objs, list) {
- if (!obj->is_patch)
+ if (!obj->is_patch) {
continue;
+ }
list_for_each_entry(patch, &obj->applied_patch, list) {
- if (strncmp(patch->uinfo->id, uuid, UPATCH_ID_LEN) == 0)
+ if (strncmp(patch->uinfo->id, uuid, UPATCH_ID_LEN) == 0) {
return -EEXIST;
}
+ }
}
return 0;
}
@@ -707,15 +698,16 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
// 查看process的信息pid: maps, mem, cmdline, exe
ret = upatch_process_init(&proc, pid);
if (ret < 0) {
- log_error("cannot init process %d\n", pid);
+ log_error("Failed to init process %d, ret=%d\n", pid, ret);
goto out;
}
upatch_process_print_short(&proc);
ret = upatch_process_mem_open(&proc, MEM_READ);
- if (ret < 0)
+ if (ret < 0) {
goto out_free;
+ }
// use uprobe to hack function. the program has been executed to the entry
// point
@@ -736,7 +728,7 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
}
ret = binary_init(relf, binary_path);
if (ret) {
- log_error("binary_init failed %d \n", ret);
+ log_error("Failed to load binary, ret=%d\n", ret);
goto out_free;
}
@@ -759,7 +751,9 @@ int process_patch(int pid, struct upatch_elf *uelf, struct running_elf *relf, co
ret = 0;
out_free:
- upatch_process_memfree(&proc);
+ upatch_process_detach(&proc);
+ upatch_process_destroy(&proc);
+
out:
if (is_calc_time) {
gettimeofday(&end_tv, NULL);
@@ -856,18 +850,22 @@ int process_unpatch(int pid, const char *uuid)
/* Finally, attach to process */
ret = upatch_process_attach(&proc);
- if (ret < 0)
+ if (ret < 0) {
goto out_free;
+ }
// 应用
ret = upatch_unapply_patches(&proc, uuid);
- if (ret < 0)
+ if (ret < 0) {
goto out_free;
+ }
ret = 0;
out_free:
- upatch_process_memfree(&proc);
+ upatch_process_detach(&proc);
+ upatch_process_destroy(&proc);
+
out:
if (is_calc_time) {
gettimeofday(&end_tv, NULL);
@@ -916,29 +914,33 @@ int process_info(int pid)
// 查看process的信息pid: maps, mem, cmdline, exe
ret = upatch_process_init(&proc, pid);
if (ret < 0) {
- log_error("cannot init process %d\n", pid);
+ log_error("Failed to init process %d, ret=%d\n", pid, ret);
goto out;
}
ret = upatch_process_mem_open(&proc, MEM_READ);
- if (ret < 0)
+ if (ret < 0) {
goto out_free;
+ }
ret = upatch_process_map_object_files(&proc, NULL);
- if (ret < 0)
+ if (ret < 0) {
goto out_free;
+ }
- // 应用
ret = upatch_info(&proc);
- if (ret)
+ if (ret) {
status = "active";
- else
+ }
+ else {
status = "removed";
+ }
ret = 0;
out_free:
- upatch_process_memfree(&proc);
+ upatch_process_destroy(&proc);
+
out:
log_normal("%s\n", status);
return ret;
diff --git a/upatch/upatch-manage/upatch-process.c b/upatch/upatch-manage/upatch-process.c
index 2437ce1..aeb5705 100644
--- a/upatch/upatch-manage/upatch-process.c
+++ b/upatch/upatch-manage/upatch-process.c
@@ -19,6 +19,8 @@
#include "upatch-process.h"
#include "upatch-ptrace.h"
+static const int MAX_ATTACH_ATTEMPTS = 3;
+
/*
* Locks process by opening /proc/<pid>/maps
* This ensures that task_struct will not be
@@ -32,17 +34,26 @@ static int lock_process(int pid)
log_debug("Locking PID %d...", pid);
snprintf(path, sizeof(path), "/proc/%d/maps", pid);
+
fd = open(path, O_RDONLY);
if (fd < 0) {
- log_error("cannot open '/proc/%d/maps'\n", pid);
+ log_error("Failed to open '%s'\n", path);
return -1;
}
log_debug("OK\n");
+
return fd;
}
+static void unlock_process(int pid, int fdmaps)
+{
+ int errsv = errno;
+ close(fdmaps);
+ errno = errsv;
+}
+
// TODO: get addr_space
-int upatch_coroutines_init(struct upatch_process *proc)
+static int upatch_coroutines_init(struct upatch_process *proc)
{
INIT_LIST_HEAD(&proc->coro.coros);
@@ -56,17 +67,20 @@ static int process_get_comm(struct upatch_process *proc)
char *bn, *c;
ssize_t ret;
- log_debug("process_get_comm %d...", proc->pid);
snprintf(path, sizeof(path), "/proc/%d/exe", proc->pid);
+ log_debug("Reading from '%s'...", path);
ret = readlink(path, realpath, sizeof(realpath));
- if (ret < 0)
+ if (ret < 0) {
return -1;
+ }
+
realpath[ret] = '\0';
bn = basename(realpath);
strncpy(path, bn, sizeof(path) - 1);
- if ((c = strstr(path, " (deleted)")))
+ if ((c = strstr(path, " (deleted)"))) {
*c = '\0';
+ }
proc->comm[sizeof(proc->comm) - 1] = '\0';
memcpy(proc->comm, path, sizeof(proc->comm) - 1);
@@ -76,20 +90,14 @@ static int process_get_comm(struct upatch_process *proc)
return 0;
}
-static void unlock_process(int pid, int fdmaps)
-{
- int errsv = errno;
- close(fdmaps);
- errno = errsv;
-}
-
int upatch_process_init(struct upatch_process *proc, int pid)
{
int fdmaps;
fdmaps = lock_process(pid);
- if (fdmaps < 0)
+ if (fdmaps < 0) {
goto out_err;
+ }
memset(proc, 0, sizeof(*proc));
@@ -102,10 +110,13 @@ int upatch_process_init(struct upatch_process *proc, int pid)
INIT_LIST_HEAD(&proc->vmaholes);
proc->num_objs = 0;
- if (upatch_coroutines_init(proc))
+ if (upatch_coroutines_init(proc)) {
goto out_unlock;
- if (process_get_comm(proc))
+ }
+
+ if (process_get_comm(proc)) {
goto out_unlock;
+ }
return 0;
@@ -115,15 +126,63 @@ out_err:
return -1;
}
+static void upatch_object_memfree(struct object_file *obj)
+{
+ struct object_patch *opatch, *opatch_safe;
+ struct obj_vm_area *ovma, *ovma_safe;
+
+ if (obj->name) {
+ free(obj->name);
+ }
+
+ list_for_each_entry_safe(opatch, opatch_safe, &obj->applied_patch, list) {
+ if (opatch->uinfo) {
+ free(opatch->uinfo);
+ }
+ if (opatch->funcs) {
+ free(opatch->funcs);
+ }
+ free(opatch);
+ }
+
+ list_for_each_entry_safe(ovma, ovma_safe, &obj->vma, list) {
+ free(ovma);
+ }
+}
+
+static void upatch_process_memfree(struct upatch_process *proc)
+{
+ struct upatch_ptrace_ctx *p, *p_safe;
+ struct object_file *obj, *obj_safe;
+ struct vm_hole *hole, *hole_safe;
+
+ list_for_each_entry_safe(p, p_safe, &proc->ptrace.pctxs, list) {
+ free(p);
+ }
+
+ list_for_each_entry_safe(hole, hole_safe, &proc->vmaholes, list) {
+ free(hole);
+ }
+
+ list_for_each_entry_safe(obj, obj_safe, &proc->objs, list) {
+ upatch_object_memfree(obj);
+ free(obj);
+ }
+}
+
+void upatch_process_destroy(struct upatch_process *proc)
+{
+ unlock_process(proc->pid, proc->fdmaps);
+ upatch_process_memfree(proc);
+}
+
static void process_print_cmdline(struct upatch_process *proc)
{
- char buf[1024];
- int fd;
+ char buf[PATH_MAX];
ssize_t i, rv;
- snprintf(buf, sizeof("/proc/0123456789/cmdline"), "/proc/%d/cmdline",
- proc->pid);
- fd = open(buf, O_RDONLY);
+ snprintf(buf, PATH_MAX, "/proc/%d/cmdline", proc->pid);
+ int fd = open(buf, O_RDONLY);
if (fd == -1) {
log_error("open\n");
return;
@@ -144,10 +203,12 @@ static void process_print_cmdline(struct upatch_process *proc)
break;
for (i = 0; i < rv; i++) {
- if (buf[i] != '\n' && isprint(buf[i]))
+ if (buf[i] != '\n' && isprint(buf[i])) {
putchar(buf[i]);
- else
+ }
+ else {
printf("\\x%02x", (unsigned char)buf[i]);
+ }
}
}
@@ -164,7 +225,7 @@ void upatch_process_print_short(struct upatch_process *proc)
int upatch_process_mem_open(struct upatch_process *proc, int mode)
{
- char path[sizeof("/proc/0123456789/mem")];
+ char path[PATH_MAX];
if (proc->memfd >= 0) {
close(proc->memfd);
@@ -272,7 +333,7 @@ process_new_object(struct upatch_process *proc, dev_t dev, int inode,
o = malloc(sizeof(*o));
if (!o) {
- log_error("FAIL\n");
+ log_error("FAILED\n");
return NULL;
}
memset(o, 0, sizeof(struct object_file));
@@ -288,7 +349,7 @@ process_new_object(struct upatch_process *proc, dev_t dev, int inode,
o->previous_hole = hole;
if (object_add_vm_area(o, vma, hole) < 0) {
- log_error("can't add vm_area for %s\n", name);
+ log_error("Cannot add vm area for %s\n", name);
free(o);
return NULL;
}
@@ -298,6 +359,7 @@ process_new_object(struct upatch_process *proc, dev_t dev, int inode,
list_add(&o->list, &proc->objs);
proc->num_objs++;
+
log_debug("OK\n");
return o;
}
@@ -332,19 +394,22 @@ static int process_add_object_vma(struct upatch_process *proc, dev_t dev,
}
o = process_new_object(proc, dev, inode, name, vma, hole);
- if (o == NULL)
+ if (o == NULL) {
return -1;
+ }
if (object_type == OBJECT_UPATCH) {
struct object_patch *opatch;
opatch = malloc(sizeof(struct object_patch));
- if (opatch == NULL)
+ if (opatch == NULL) {
return -1;
+ }
opatch->uinfo = malloc(sizeof(struct upatch_info));
- if (opatch->uinfo == NULL)
+ if (opatch->uinfo == NULL) {
return -1;
+ }
memcpy(opatch->uinfo, header_buf, sizeof(struct upatch_info));
opatch->funcs = malloc(opatch->uinfo->changed_func_num *
@@ -372,7 +437,7 @@ static int process_add_object_vma(struct upatch_process *proc, dev_t dev,
int upatch_process_parse_proc_maps(struct upatch_process *proc)
{
FILE *f;
- int ret, fd, is_libc_base_set = 0;
+ int ret, is_libc_base_set = 0;
unsigned long hole_start = 0;
struct vm_hole *hole = NULL;
@@ -383,7 +448,7 @@ int upatch_process_parse_proc_maps(struct upatch_process *proc)
* of the object (we might have references to them
* in the patch).
*/
- fd = dup(proc->fdmaps);
+ int fd = dup(proc->fdmaps);
if (fd < 0) {
log_error("unable to dup fd %d", proc->fdmaps);
return -1;
@@ -405,17 +470,20 @@ int upatch_process_parse_proc_maps(struct upatch_process *proc)
char perms[5], name_[256], *name = name_;
int r;
- if (!fgets(line, sizeof(line), f))
+ if (!fgets(line, sizeof(line), f)) {
break;
+ }
+
r = sscanf(line, "%lx-%lx %s %lx %x:%x %d %255s", &start, &end,
perms, &offset, &maj, &min, &inode, name_);
-
if (r == EOF) {
- log_error("sscanf failed: end of file");
+ log_error("Failed to read maps: unexpected EOF");
goto error;
}
- if (r != 8)
+
+ if (r != 8) {
strcpy(name, "[anonymous]");
+ }
vma.start = start;
vma.end = end;
@@ -451,7 +519,7 @@ int upatch_process_parse_proc_maps(struct upatch_process *proc)
} while (1);
fclose(f);
- log_debug("Found %d object file(s) \n", proc->num_objs);
+ log_debug("Found %d object file(s)\n", proc->num_objs);
if (!is_libc_base_set) {
log_error("Can't find libc_base required for manipulations: %d",
@@ -497,29 +565,30 @@ static int process_list_threads(struct upatch_process *proc, int **ppids,
{
DIR *dir = NULL;
struct dirent *de;
- char path[128];
+ char path[PATH_MAX];
int *pids = *ppids;
snprintf(path, sizeof(path), "/proc/%d/task", proc->pid);
+
dir = opendir(path);
if (!dir) {
- log_error("can't open '%s' directory\n", path);
+ log_error("Failed to open directory '%s'\n", path);
goto dealloc;
}
*npids = 0;
while ((de = readdir(dir))) {
int *t;
- if (de->d_name[0] == '.')
+ if (de->d_name[0] == '.') {
continue;
+ }
if (*npids >= *alloc) {
*alloc = *alloc ? *alloc * 2 : 1;
t = realloc(pids, *alloc * sizeof(*pids));
if (t == NULL) {
- log_error(
- "Failed to (re)allocate memory for pids\n");
+ log_error("Failed to (re)allocate memory for pids\n");
goto dealloc;
}
@@ -536,62 +605,25 @@ static int process_list_threads(struct upatch_process *proc, int **ppids,
return *npids;
dealloc:
- if (dir)
+ if (dir) {
closedir(dir);
+ }
free(pids);
*ppids = NULL;
*alloc = *npids = 0;
return -1;
}
-static void process_detach(struct upatch_process *proc)
-{
- struct upatch_ptrace_ctx *p, *ptmp;
- int status;
- pid_t pid;
-
- if (proc->memfd >= 0 && close(proc->memfd) < 0)
- log_error("can't close memfd");
- proc->memfd = -1;
-
- list_for_each_entry_safe(p, ptmp, &proc->ptrace.pctxs, list) {
- /**
- * If upatch_ptrace_detach(p) return -ESRCH, there are two situations,
- * as described below:
- * 1. the specified thread does not exist, it means the thread dead
- * during the attach processing, so we need to wait for the thread
- * to exit;
- * 2. the specified thread is not currently being traced by us,
- * or is not stopped, so we just ignore it;
- *
- * We using the running variable of the struct upatch_ptrace_ctx to
- * distinguish them:
- * 1. if pctx->running = 0, it means the thread is traced by us, we
- * will wait for the thread to exit;
- * 2. if pctx->running = 1, it means we can not sure about the status of
- * the thread, we just ignore it;
- */
- if (upatch_ptrace_detach(p) == -ESRCH && !p->running) {
- do {
- pid = waitpid(p->pid, &status, __WALL);
- } while (pid > 0 && !WIFEXITED(status));
- }
- // upatch_ptrace_ctx_destroy(p);
- }
- log_debug("Finished ptrace detaching.\n");
-}
-
-static const int max_attach_attempts = 3;
-
int upatch_process_attach(struct upatch_process *proc)
{
int *pids = NULL, ret;
size_t i, npids = 0, alloc = 0, prevnpids = 0, nattempts;
- if (upatch_process_mem_open(proc, MEM_WRITE) < 0)
+ if (upatch_process_mem_open(proc, MEM_WRITE) < 0) {
return -1;
+ }
- for (nattempts = 0; nattempts < max_attach_attempts; nattempts++) {
+ for (nattempts = 0; nattempts < MAX_ATTACH_ATTEMPTS; nattempts++) {
ret = process_list_threads(proc, &pids, &npids, &alloc);
if (ret == -1)
goto detach;
@@ -627,25 +659,64 @@ int upatch_process_attach(struct upatch_process *proc)
prevnpids = npids;
}
- if (nattempts == max_attach_attempts) {
- log_error("unable to catch up with process, bailing\n");
+ if (nattempts == MAX_ATTACH_ATTEMPTS) {
+ log_error("Unable to catch up with process, bailing\n");
goto detach;
}
- log_debug("attached to %lu thread(s): %d", npids, pids[0]);
- for (i = 1; i < npids; i++)
+ log_debug("Attached to %lu thread(s): %d", npids, pids[0]);
+ for (i = 1; i < npids; i++) {
log_debug(", %d", pids[i]);
+ }
log_debug("\n");
free(pids);
return 0;
detach:
- process_detach(proc);
+ upatch_process_detach(proc);
free(pids);
return -1;
}
+void upatch_process_detach(struct upatch_process *proc)
+{
+ struct upatch_ptrace_ctx *p, *ptmp;
+ int status;
+ pid_t pid;
+
+ if (proc->memfd >= 0 && close(proc->memfd) < 0) {
+ log_error("Failed to close memfd");
+ }
+ proc->memfd = -1;
+
+ list_for_each_entry_safe(p, ptmp, &proc->ptrace.pctxs, list) {
+ /**
+ * If upatch_ptrace_detach(p) return -ESRCH, there are two situations,
+ * as described below:
+ * 1. the specified thread does not exist, it means the thread dead
+ * during the attach processing, so we need to wait for the thread
+ * to exit;
+ * 2. the specified thread is not currently being traced by us,
+ * or is not stopped, so we just ignore it;
+ *
+ * We using the running variable of the struct upatch_ptrace_ctx to
+ * distinguish them:
+ * 1. if pctx->running = 0, it means the thread is traced by us, we
+ * will wait for the thread to exit;
+ * 2. if pctx->running = 1, it means we can not sure about the status of
+ * the thread, we just ignore it;
+ */
+ if (upatch_ptrace_detach(p) == -ESRCH && !p->running) {
+ do {
+ pid = waitpid(p->pid, &status, __WALL);
+ } while (pid > 0 && !WIFEXITED(status));
+ }
+ // upatch_ptrace_ctx_destroy(p);
+ }
+ log_debug("Process detached\n");
+}
+
static inline struct vm_hole *next_hole(struct vm_hole *hole,
struct list_head *head)
{
@@ -765,13 +836,12 @@ unsigned long object_find_patch_region(struct object_file *obj, size_t memsize,
}
if (region_start == region_end) {
- log_error("can't find suitable region for patch on '%s'\n",
- obj->name);
+ log_error("Cannot find suitable region for patch '%s'\n", obj->name);
return -1UL;
}
region_start = (region_start >> PAGE_SHIFT) << PAGE_SHIFT;
- log_debug("Found patch region for '%s' at %lx\n", obj->name,
+ log_debug("Found patch region for '%s' at 0x%lx\n", obj->name,
region_start);
return region_start;
@@ -801,58 +871,12 @@ unsigned long object_find_patch_region_nolimit(struct object_file *obj, size_t m
left_hole = prev_hole(left_hole, head);
}
- log_error("can't find suitable region for patch on '%s'\n",
- obj->name);
+ log_error("Cannot find suitable region for patch '%s'\n", obj->name);
return -1UL;
found:
region_start = ((*hole)->start >> PAGE_SHIFT) << PAGE_SHIFT;
- log_debug("Found patch region for '%s' at %lx\n", obj->name,
+ log_debug("Found patch region for '%s' 0xat %lx\n", obj->name,
region_start);
return region_start;
}
-
-static void upatch_object_memfree(struct object_file *obj)
-{
- struct object_patch *opatch, *opatch_safe;
- struct obj_vm_area *ovma, *ovma_safe;
-
- if (obj->name)
- free(obj->name);
-
- list_for_each_entry_safe(opatch, opatch_safe, &obj->applied_patch,
- list) {
- if (opatch->uinfo)
- free(opatch->uinfo);
- if (opatch->funcs)
- free(opatch->funcs);
- free(opatch);
- }
-
- list_for_each_entry_safe(ovma, ovma_safe, &obj->vma, list) {
- free(ovma);
- }
-}
-
-void upatch_process_memfree(struct upatch_process *proc)
-{
- struct upatch_ptrace_ctx *p, *p_safe;
- struct object_file *obj, *obj_safe;
- struct vm_hole *hole, *hole_safe;
-
- list_for_each_entry_safe(p, p_safe, &proc->ptrace.pctxs, list) {
- free(p);
- }
-
- list_for_each_entry_safe(hole, hole_safe, &proc->vmaholes, list) {
- free(hole);
- }
-
- list_for_each_entry_safe(obj, obj_safe, &proc->objs, list) {
- upatch_object_memfree(obj);
- free(obj);
- }
-
- unlock_process(proc->pid, proc->fdmaps);
- process_detach(proc);
-}
diff --git a/upatch/upatch-manage/upatch-process.h b/upatch/upatch-manage/upatch-process.h
index 9c3aecc..2a212fa 100644
--- a/upatch/upatch-manage/upatch-process.h
+++ b/upatch/upatch-manage/upatch-process.h
@@ -107,6 +107,8 @@ struct upatch_process {
int upatch_process_init(struct upatch_process *, int);
+void upatch_process_destroy(struct upatch_process *);
+
void upatch_process_print_short(struct upatch_process *);
int upatch_process_mem_open(struct upatch_process *, int);
@@ -115,6 +117,8 @@ int upatch_process_map_object_files(struct upatch_process *, const char *);
int upatch_process_attach(struct upatch_process *);
+void upatch_process_detach(struct upatch_process *proc);
+
int vm_hole_split(struct vm_hole *, unsigned long, unsigned long);
unsigned long object_find_patch_region(struct object_file *, size_t,
@@ -122,6 +126,4 @@ unsigned long object_find_patch_region(struct object_file *, size_t,
unsigned long object_find_patch_region_nolimit(struct object_file *, size_t,
struct vm_hole **);
-void upatch_process_memfree(struct upatch_process *);
-
#endif
diff --git a/upatch/upatch-manage/upatch-ptrace.c b/upatch/upatch-manage/upatch-ptrace.c
index 4144fbe..4c9944a 100644
--- a/upatch/upatch-manage/upatch-ptrace.c
+++ b/upatch/upatch-manage/upatch-ptrace.c
@@ -12,27 +12,23 @@
/* process's memory access */
int upatch_process_mem_read(struct upatch_process *proc, unsigned long src,
- void *dst, size_t size)
+ void *dst, size_t size)
{
- ssize_t r;
-
- r = pread(proc->memfd, dst, size, (off_t)src);
+ ssize_t r = pread(proc->memfd, dst, size, (off_t)src);
return r != size ? -1 : 0;
}
static int upatch_process_mem_write_ptrace(struct upatch_process *proc,
- void *src, unsigned long dst,
- size_t size)
+ void *src, unsigned long dst, size_t size)
{
int ret;
while (ROUND_DOWN(size, sizeof(long)) != 0) {
- ret = ptrace(PTRACE_POKEDATA, proc->pid, dst,
- *(unsigned long *)src);
- if (ret)
+ ret = ptrace(PTRACE_POKEDATA, proc->pid, dst, *(unsigned long *)src);
+ if (ret) {
return -1;
-
+ }
dst += sizeof(long);
src += sizeof(long);
size -= sizeof(long);
@@ -42,26 +38,29 @@ static int upatch_process_mem_write_ptrace(struct upatch_process *proc,
unsigned long tmp;
tmp = ptrace(PTRACE_PEEKDATA, proc->pid, dst, NULL);
- if (tmp == (unsigned long)-1 && errno)
+ if (tmp == (unsigned long)-1 && errno) {
return -1;
+ }
memcpy(&tmp, src, size);
ret = ptrace(PTRACE_POKEDATA, proc->pid, dst, tmp);
- if (ret)
+ if (ret) {
return -1;
+ }
}
return 0;
}
int upatch_process_mem_write(struct upatch_process *proc, void *src,
- unsigned long dst, size_t size)
+ unsigned long dst, size_t size)
{
static int use_pwrite = 1;
ssize_t w;
- if (use_pwrite)
+ if (use_pwrite) {
w = pwrite(proc->memfd, src, size, (off_t)dst);
+ }
if (!use_pwrite || (w == -1 && errno == EINVAL)) {
use_pwrite = 0;
return upatch_process_mem_write_ptrace(proc, src, dst, size);
@@ -70,14 +69,16 @@ int upatch_process_mem_write(struct upatch_process *proc, void *src,
return w != size ? -1 : 0;
}
-static struct upatch_ptrace_ctx *
-upatch_ptrace_ctx_alloc(struct upatch_process *proc)
+static struct upatch_ptrace_ctx* upatch_ptrace_ctx_alloc(
+ struct upatch_process *proc)
{
struct upatch_ptrace_ctx *p;
p = malloc(sizeof(*p));
- if (!p)
+ if (!p) {
return NULL;
+ }
+
memset(p, 0, sizeof(*p));
p->execute_until = 0UL;
@@ -86,56 +87,54 @@ upatch_ptrace_ctx_alloc(struct upatch_process *proc)
INIT_LIST_HEAD(&p->list);
list_add(&p->list, &proc->ptrace.pctxs);
+
return p;
}
int upatch_ptrace_attach_thread(struct upatch_process *proc, int tid)
{
- long ret;
- int status;
- struct upatch_ptrace_ctx *pctx;
-
- pctx = upatch_ptrace_ctx_alloc(proc);
+ struct upatch_ptrace_ctx *pctx = upatch_ptrace_ctx_alloc(proc);
if (pctx == NULL) {
- log_error("Can't alloc upatch_ptrace_ctx");
+ log_error("Failed to alloc ptrace context");
return -1;
}
pctx->pid = tid;
- log_debug("Attaching to %d...", pctx->pid);
+ log_debug("Attaching to %d...", tid);
- ret = ptrace(PTRACE_ATTACH, pctx->pid, NULL, NULL);
+ long ret = ptrace(PTRACE_ATTACH, tid, NULL, NULL);
if (ret < 0) {
- log_error("can't attach to %d\n", pctx->pid);
+ log_error("Failed to attach thread, pid=%d, ret=%ld\n", tid, ret);
return -1;
}
do {
+ int status = 0;
+
ret = waitpid(tid, &status, __WALL);
if (ret < 0) {
- log_error("can't wait for thread\n");
+ log_error("Failed to wait thread, tid=%d, ret=%ld\n", tid, ret);
return -1;
}
/* We are expecting SIGSTOP */
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
+ if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP) {
break;
+ }
/* If we got SIGTRAP because we just got out of execve, wait
* for the SIGSTOP
*/
- if (WIFSTOPPED(status))
- status = (WSTOPSIG(status) == SIGTRAP) ?
- 0 :
- WSTOPSIG(status);
- else if (WIFSIGNALED(status))
+ if (WIFSTOPPED(status)) {
+ status = (WSTOPSIG(status) == SIGTRAP) ? 0 : WSTOPSIG(status);
+ } else if (WIFSIGNALED(status)) {
/* Resend signal */
status = WTERMSIG(status);
+ }
- ret = ptrace(PTRACE_CONT, pctx->pid, NULL,
- (void *)(uintptr_t)status);
+ ret = ptrace(PTRACE_CONT, tid, NULL, (void *)(uintptr_t)status);
if (ret < 0) {
- log_error("can't cont tracee\n");
+ log_error("Failed to continue thread, tid=%d, ret=%ld\n", tid, ret);
return -1;
}
} while (1);
@@ -152,23 +151,22 @@ int wait_for_stop(struct upatch_ptrace_ctx *pctx, const void *data)
log_debug("wait_for_stop(pctx->pid=%d, pid=%d)\n", pctx->pid, pid);
while (1) {
- ret = ptrace(PTRACE_CONT, pctx->pid, NULL,
- (void *)(uintptr_t)status);
+ ret = ptrace(PTRACE_CONT, pctx->pid, NULL, (void *)(uintptr_t)status);
if (ret < 0) {
- log_error("can't start tracee %d\n", pctx->pid);
+ log_error("Cannot start tracee %d, ret=%d\n", pctx->pid, ret);
return -1;
}
ret = waitpid(pid, &status, __WALL);
if (ret < 0) {
- log_error("can't wait tracee %d\n", pid);
+ log_error("Cannot wait tracee %d, ret=%d\n", pid, ret);
return -1;
}
if (WIFSTOPPED(status)) {
- if (WSTOPSIG(status) == SIGSTOP ||
- WSTOPSIG(status) == SIGTRAP)
+ if (WSTOPSIG(status) == SIGSTOP || WSTOPSIG(status) == SIGTRAP) {
break;
+ }
status = WSTOPSIG(status);
continue;
}
@@ -181,17 +179,16 @@ int wait_for_stop(struct upatch_ptrace_ctx *pctx, const void *data)
int upatch_ptrace_detach(struct upatch_ptrace_ctx *pctx)
{
- long ret;
-
- if (!pctx->pid)
+ if (!pctx->pid) {
return 0;
- log_debug("Detaching from %d...\n", pctx->pid);
- ret = ptrace(PTRACE_DETACH, pctx->pid, NULL, NULL);
+ }
+
+ log_debug("Detaching from %d...", pctx->pid);
+ long ret = ptrace(PTRACE_DETACH, pctx->pid, NULL, NULL);
if (ret < 0) {
- log_error("can't detach from %d\n", pctx->pid);
+ log_error("Failed to detach from process, pid=%d, ret=%ld\n", pctx->pid, ret);
return -errno;
}
-
log_debug("OK\n");
pctx->running = 1;
@@ -200,16 +197,16 @@ int upatch_ptrace_detach(struct upatch_ptrace_ctx *pctx)
}
int upatch_execute_remote(struct upatch_ptrace_ctx *pctx,
- const unsigned char *code, size_t codelen,
- struct user_regs_struct *pregs)
+ const unsigned char *code, size_t codelen,
+ struct user_regs_struct *pregs)
{
- return upatch_arch_execute_remote_func(pctx, code, codelen, pregs,
- wait_for_stop, NULL);
+ return upatch_arch_execute_remote_func(
+ pctx, code, codelen, pregs, wait_for_stop, NULL);
}
unsigned long upatch_mmap_remote(struct upatch_ptrace_ctx *pctx,
- unsigned long addr, size_t length, int prot,
- int flags, int fd, off_t offset)
+ unsigned long addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
{
int ret;
unsigned long res = 0;
@@ -218,8 +215,9 @@ unsigned long upatch_mmap_remote(struct upatch_ptrace_ctx *pctx,
prot, flags, fd, offset);
ret = upatch_arch_syscall_remote(pctx, __NR_mmap, (unsigned long)addr,
length, prot, flags, fd, offset, &res);
- if (ret < 0)
+ if (ret < 0) {
return 0;
+ }
if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) {
errno = -(long)res;
return 0;
@@ -228,7 +226,7 @@ unsigned long upatch_mmap_remote(struct upatch_ptrace_ctx *pctx,
}
int upatch_mprotect_remote(struct upatch_ptrace_ctx *pctx, unsigned long addr,
- size_t length, int prot)
+ size_t length, int prot)
{
int ret;
unsigned long res;
@@ -248,7 +246,7 @@ int upatch_mprotect_remote(struct upatch_ptrace_ctx *pctx, unsigned long addr,
}
int upatch_munmap_remote(struct upatch_ptrace_ctx *pctx, unsigned long addr,
- size_t length)
+ size_t length)
{
int ret;
unsigned long res;
diff --git a/upatch/upatch-manage/upatch-relocation.c b/upatch/upatch-manage/upatch-relocation.c
index 4c9c360..1baeecf 100644
--- a/upatch/upatch-manage/upatch-relocation.c
+++ b/upatch/upatch-manage/upatch-relocation.c
@@ -31,11 +31,10 @@ int apply_relocations(struct upatch_elf *uelf)
if (!(uelf->info.shdrs[infosec].sh_flags & SHF_ALLOC))
continue;
+ log_debug("Relocate '%s'\n", name);
if (uelf->info.shdrs[i].sh_type == SHT_REL) {
- log_error("do rel relocations for %s \n", name);
return -EPERM;
} else if (uelf->info.shdrs[i].sh_type == SHT_RELA) {
- log_debug("do rela relocations for %s \n", name);
err = apply_relocate_add(uelf, uelf->index.sym, i);
}
diff --git a/upatch/upatch-manage/upatch-resolve.c b/upatch/upatch-manage/upatch-resolve.c
index 9c140fe..1a462d9 100644
--- a/upatch/upatch-manage/upatch-resolve.c
+++ b/upatch/upatch-manage/upatch-resolve.c
@@ -121,7 +121,7 @@ static unsigned long resolve_rela_plt(struct upatch_elf *uelf,
unsigned long sym_addr = relf->load_bias + rela_plt[i].r_offset;
elf_addr = insert_plt_table(uelf, obj, GELF_R_TYPE(rela_plt[i].r_info), sym_addr);
- log_debug("resolved %s from .rela_plt at 0x%lx\n", name, elf_addr);
+ log_debug("Resolved '%s' from '.rela_plt' at 0x%lx\n", name, elf_addr);
break;
}
@@ -160,7 +160,7 @@ static unsigned long resolve_dynsym(struct upatch_elf *uelf,
unsigned long sym_addr = relf->load_bias + dynsym[i].st_value;
elf_addr = insert_got_table(uelf, obj, 0, sym_addr);
- log_debug("resolved %s from .dynsym at 0x%lx\n", name, elf_addr);
+ log_debug("Resolved '%s' from '.dynsym' at 0x%lx\n", name, elf_addr);
break;
}
@@ -198,7 +198,7 @@ static unsigned long resolve_sym(struct upatch_elf *uelf,
elf_addr = relf->load_bias + sym[i].st_value;
- log_debug("resolved %s from .sym at 0x%lx\n", name, elf_addr);
+ log_debug("Resolved '%s' from '.sym' at 0x%lx\n", name, elf_addr);
break;
}
@@ -220,7 +220,7 @@ static unsigned long resolve_patch_sym(struct upatch_elf *uelf,
}
elf_addr = relf->load_bias + patch_sym->st_value;
- log_debug("resolved %s from patch .sym at 0x%lx\n", name, elf_addr);
+ log_debug("Resolved '%s' from patch '.sym' at 0x%lx\n", name, elf_addr);
return elf_addr;
}
@@ -268,7 +268,7 @@ static unsigned long resolve_symbol(struct upatch_elf *uelf,
}
if (!elf_addr) {
- log_error("Cannot resolve symbol %s\n", name);
+ log_error("Cannot resolve symbol '%s'\n", name);
}
return elf_addr;
}
@@ -286,38 +286,37 @@ int simplify_symbols(struct upatch_elf *uelf, struct object_file *obj)
if (GELF_ST_TYPE(sym[i].st_info) == STT_SECTION &&
sym[i].st_shndx < uelf->info.hdr->e_shnum)
- name = uelf->info.shstrtab +
- uelf->info.shdrs[sym[i].st_shndx].sh_name;
+ name = uelf->info.shstrtab + uelf->info.shdrs[sym[i].st_shndx].sh_name;
else
name = uelf->strtab + sym[i].st_name;
switch (sym[i].st_shndx) {
case SHN_COMMON:
- log_debug("unsupported Common symbol: %s\n", name);
+ log_debug("Unsupported common symbol '%s'\n", name);
ret = -ENOEXEC;
break;
case SHN_ABS:
break;
case SHN_UNDEF:
elf_addr = resolve_symbol(uelf, obj, name, sym[i]);
- if (!elf_addr)
+ if (!elf_addr) {
ret = -ENOEXEC;
+ }
sym[i].st_value = elf_addr;
- log_debug("resolved symbol %s at 0x%lx\n", name,
- (unsigned long)sym[i].st_value);
+ log_debug("Resolved symbol '%s' at 0x%lx\n",
+ name, (unsigned long)sym[i].st_value);
break;
case SHN_LIVEPATCH:
sym[i].st_value += uelf->relf->load_bias;
- log_debug("resolved livepatch symbol %s at 0x%lx\n",
+ log_debug("Resolved livepatch symbol '%s' at 0x%lx\n",
name, (unsigned long)sym[i].st_value);
break;
default:
/* use real address to calculate secbase */
- secbase =
- uelf->info.shdrs[sym[i].st_shndx].sh_addralign;
+ secbase = uelf->info.shdrs[sym[i].st_shndx].sh_addralign;
sym[i].st_value += secbase;
- log_debug("normal symbol %s at 0x%lx\n", name,
- (unsigned long)sym[i].st_value);
+ log_debug("Symbol '%s' at 0x%lx\n",
+ name, (unsigned long)sym[i].st_value);
break;
}
}
--
2.33.0