From 05b64620354b8f8bd36c3f782eff9cd145f57fea Mon Sep 17 00:00:00 2001 From: Jiajie Li Date: Tue, 13 Oct 2020 11:10:11 +0800 Subject: [PATCH 45/89] kpatch_ptrace: Split function wait_for_mmap The function wait_for_mmap is arch related, so 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 | 58 ++++++++++++++++++++++++++++++++++ src/arch/x86/arch_ptrace.c | 58 ++++++++++++++++++++++++++++++++++ src/include/kpatch_ptrace.h | 3 ++ src/kpatch_ptrace.c | 58 ---------------------------------- 4 files changed, 119 insertions(+), 58 deletions(-) diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c index a444285..b21189e 100644 --- a/src/arch/aarch64/arch_ptrace.c +++ b/src/arch/aarch64/arch_ptrace.c @@ -22,6 +22,64 @@ #include +int +wait_for_mmap(struct kpatch_ptrace_ctx *pctx, + unsigned long *pbase) +{ + int ret, status = 0, insyscall = 0; + long rv; + + while (1) { + ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL, + (void *)(uintptr_t)status); + if (ret < 0) { + kplogerror("can't PTRACE_SYSCALL tracee - %d\n", + pctx->pid); + return -1; + } + + ret = waitpid(pctx->pid, &status, __WALL); + if (ret < 0) { + kplogerror("can't wait tracee - %d\n", pctx->pid); + return -1; + } + + if (WIFEXITED(status)) { + status = WTERMSIG(status); + continue; + } else if (!WIFSTOPPED(status)) { + status = 0; + continue; + } + + status = 0; + + if (insyscall == 0) { + rv = ptrace(PTRACE_PEEKUSER, pctx->pid, + offsetof(struct user_regs_struct, + regs[29]), + NULL); + if (rv == -1) { + kplogerror("ptrace(PTRACE_PEEKUSER)\n"); + return -1; + } + insyscall = rv; + continue; + } else if (insyscall == __NR_mmap) { + rv = ptrace(PTRACE_PEEKUSER, pctx->pid, + offsetof(struct user_regs_struct, + regs[8]), + NULL); + *pbase = rv; + break; + } + + insyscall = !insyscall; + } + + return 0; +} + int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c index 10127a3..0032cbd 100644 --- a/src/arch/x86/arch_ptrace.c +++ b/src/arch/x86/arch_ptrace.c @@ -22,6 +22,64 @@ #include +int +wait_for_mmap(struct kpatch_ptrace_ctx *pctx, + unsigned long *pbase) +{ + int ret, status = 0, insyscall = 0; + long rv; + + while (1) { + ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL, + (void *)(uintptr_t)status); + if (ret < 0) { + kplogerror("can't PTRACE_SYSCALL tracee - %d\n", + pctx->pid); + return -1; + } + + ret = waitpid(pctx->pid, &status, __WALL); + if (ret < 0) { + kplogerror("can't wait tracee - %d\n", pctx->pid); + return -1; + } + + if (WIFEXITED(status)) { + status = WTERMSIG(status); + continue; + } else if (!WIFSTOPPED(status)) { + status = 0; + continue; + } + + status = 0; + + if (insyscall == 0) { + rv = ptrace(PTRACE_PEEKUSER, pctx->pid, + offsetof(struct user_regs_struct, + orig_rax), + NULL); + if (rv == -1) { + kplogerror("ptrace(PTRACE_PEEKUSER)\n"); + return -1; + } + insyscall = rv; + continue; + } else if (insyscall == __NR_mmap) { + rv = ptrace(PTRACE_PEEKUSER, pctx->pid, + offsetof(struct user_regs_struct, + rax), + NULL); + *pbase = rv; + break; + } + + insyscall = !insyscall; + } + + return 0; +} + int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6, diff --git a/src/include/kpatch_ptrace.h b/src/include/kpatch_ptrace.h index c8cfd41..5abcf26 100644 --- a/src/include/kpatch_ptrace.h +++ b/src/include/kpatch_ptrace.h @@ -141,4 +141,7 @@ int kpatch_arch_syscall_remote(struct kpatch_ptrace_ctx *pctx, int nr, unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long *res); +int wait_for_mmap(struct kpatch_ptrace_ctx *pctx, + unsigned long *pbase); + #endif diff --git a/src/kpatch_ptrace.c b/src/kpatch_ptrace.c index 057b08a..7ab550c 100644 --- a/src/kpatch_ptrace.c +++ b/src/kpatch_ptrace.c @@ -448,64 +448,6 @@ wait_for_stop(struct kpatch_ptrace_ctx *pctx, return 0; } -static int -wait_for_mmap(struct kpatch_ptrace_ctx *pctx, - unsigned long *pbase) -{ - int ret, status = 0, insyscall = 0; - long rv; - - while (1) { - ret = ptrace(PTRACE_SYSCALL, pctx->pid, NULL, - (void *)(uintptr_t)status); - if (ret < 0) { - kplogerror("can't PTRACE_SYSCALL tracee - %d\n", - pctx->pid); - return -1; - } - - ret = waitpid(pctx->pid, &status, __WALL); - if (ret < 0) { - kplogerror("can't wait tracee - %d\n", pctx->pid); - return -1; - } - - if (WIFEXITED(status)) { - status = WTERMSIG(status); - continue; - } else if (!WIFSTOPPED(status)) { - status = 0; - continue; - } - - status = 0; - - if (insyscall == 0) { - rv = ptrace(PTRACE_PEEKUSER, pctx->pid, - offsetof(struct user_regs_struct, - orig_rax), - NULL); - if (rv == -1) { - kplogerror("ptrace(PTRACE_PEEKUSER)\n"); - return -1; - } - insyscall = rv; - continue; - } else if (insyscall == __NR_mmap) { - rv = ptrace(PTRACE_PEEKUSER, pctx->pid, - offsetof(struct user_regs_struct, - rax), - NULL); - *pbase = rv; - break; - } - - insyscall = !insyscall; - } - - return 0; -} - int kpatch_execute_remote(struct kpatch_ptrace_ctx *pctx, const unsigned char *code, -- 2.23.0