From aa39ba7326c13546f68b51d95bf55004437c3110 Mon Sep 17 00:00:00 2001 From: Jiajie Li Date: Mon, 12 Oct 2020 16:49:15 +0800 Subject: [PATCH 43/89] kpatch_ptrace: Split function kpatch_arch_prctl_remote The function kpatch_arch_prctl_remote is arch related, let's make two separate definations in arch/x86/arch_ptrace.c and arch/aarch64/arch_ptrace.c Signed-off-by: Jiajie Li Signed-off-by: Ying Fang --- src/arch/aarch64/arch_ptrace.c | 49 ++++++++++++++++++++++++++++++++++ src/arch/x86/arch_ptrace.c | 45 +++++++++++++++++++++++++++++++ src/include/kpatch_ptrace.h | 2 ++ src/kpatch_ptrace.c | 46 ------------------------------- 4 files changed, 96 insertions(+), 46 deletions(-) diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c index 4dee0e5..735927e 100644 --- a/src/arch/aarch64/arch_ptrace.c +++ b/src/arch/aarch64/arch_ptrace.c @@ -22,6 +22,55 @@ #include +int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr) +{ + struct user_regs_struct regs; + struct iovec regs_iov; + regs_iov.iov_base = ®s; + regs_iov.iov_len = sizeof(regs); + + unsigned long res, sp; + int ret; + + kpdebug("arch_prctl_remote: %d, %p\n", code, addr); + ret = ptrace(PTRACE_GETREGSET, pctx->pid, (void*)NT_PRSTATUS, (void*)®s_iov); + if (ret < 0) { + kpdebug("FAIL. Can't get regs - %s\n", strerror(errno)); + return -1; + } + ret = kpatch_process_mem_read(pctx->proc, + regs.sp, + &sp, + sizeof(sp)); + if (ret < 0) { + kplogerror("can't peek original stack data\n"); + return -1; + } + //ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.sp, 0, 0, 0, 0, &res); + if (ret < 0) + goto poke; + if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) { + errno = -(long)res; + ret = -1; + goto poke; + } + ret = kpatch_process_mem_read(pctx->proc, + regs.sp, + &res, + sizeof(res)); + if (ret < 0) + kplogerror("can't peek new stack data\n"); + +poke: + if (kpatch_process_mem_write(pctx->proc, + &sp, + regs.sp, + sizeof(sp))) + kplogerror("can't poke orig stack data\n"); + *addr = res; + return ret; +} + int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx, unsigned long *addr) { diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c index 3d49638..5f1e703 100644 --- a/src/arch/x86/arch_ptrace.c +++ b/src/arch/x86/arch_ptrace.c @@ -22,6 +22,51 @@ #include +int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr) +{ + struct user_regs_struct regs; + unsigned long res, rsp; + int ret; + + kpdebug("arch_prctl_remote: %d, %p\n", code, addr); + ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s); + if (ret < 0) { + kpdebug("FAIL. Can't get regs - %s\n", strerror(errno)); + return -1; + } + ret = kpatch_process_mem_read(pctx->proc, + regs.rsp, + &rsp, + sizeof(rsp)); + if (ret < 0) { + kplogerror("can't peek original stack data\n"); + return -1; + } + ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.rsp, 0, 0, 0, 0, &res); + if (ret < 0) + goto poke; + if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) { + errno = -(long)res; + ret = -1; + goto poke; + } + ret = kpatch_process_mem_read(pctx->proc, + regs.rsp, + &res, + sizeof(res)); + if (ret < 0) + kplogerror("can't peek new stack data\n"); + +poke: + if (kpatch_process_mem_write(pctx->proc, + &rsp, + regs.rsp, + sizeof(rsp))) + kplogerror("can't poke orig stack data\n"); + *addr = res; + return ret; +} + int kpatch_arch_ptrace_resolve_ifunc(struct kpatch_ptrace_ctx *pctx, unsigned long *addr) { diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h index 19a1b2c..ddaa9e6 100644 --- a/src/include/kpatch_ptrace.h +++ b/src/include/kpatch_ptrace.h @@ -84,6 +84,8 @@ int kpatch_munmap_remote(struct kpatch_ptrace_ctx *pctx, unsigned long addr, size_t length); + +#define MAX_ERRNO 4095 int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr); int diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c index cd961e1..4d2223e 100644 --- a/src/kpatch_ptrace.c +++ b/src/kpatch_ptrace.c @@ -672,7 +672,6 @@ static int kpatch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr, return ret; } -#define MAX_ERRNO 4095 unsigned long kpatch_mmap_remote(struct kpatch_ptrace_ctx *pctx, unsigned long addr, @@ -717,51 +716,6 @@ int kpatch_munmap_remote(struct kpatch_ptrace_ctx *pctx, return 0; } -int kpatch_arch_prctl_remote(struct kpatch_ptrace_ctx *pctx, int code, unsigned long *addr) -{ - struct user_regs_struct regs; - unsigned long res, rsp; - int ret; - - kpdebug("arch_prctl_remote: %d, %p\n", code, addr); - ret = ptrace(PTRACE_GETREGS, pctx->pid, NULL, ®s); - if (ret < 0) { - kpdebug("FAIL. Can't get regs - %s\n", strerror(errno)); - return -1; - } - ret = kpatch_process_mem_read(pctx->proc, - regs.rsp, - &rsp, - sizeof(rsp)); - if (ret < 0) { - kplogerror("can't peek original stack data\n"); - return -1; - } - ret = kpatch_syscall_remote(pctx, __NR_arch_prctl, code, regs.rsp, 0, 0, 0, 0, &res); - if (ret < 0) - goto poke; - if (ret == 0 && res >= (unsigned long)-MAX_ERRNO) { - errno = -(long)res; - ret = -1; - goto poke; - } - ret = kpatch_process_mem_read(pctx->proc, - regs.rsp, - &res, - sizeof(res)); - if (ret < 0) - kplogerror("can't peek new stack data\n"); - -poke: - if (kpatch_process_mem_write(pctx->proc, - &rsp, - regs.rsp, - sizeof(rsp))) - kplogerror("can't poke orig stack data\n"); - *addr = res; - return ret; -} - int kpatch_remote_write(struct kpatch_ptrace_ctx *pctx, unsigned long dst, -- 2.23.0