From f68f37a11f09cf923427ac1e9b7451d3c0c06e98 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Thu, 11 Jul 2013 13:46:53 +0400 Subject: [PATCH] parasite: modify process memory only for executing syscalls Signed-off-by: Andrey Vagin Signed-off-by: Pavel Emelyanov --- arch/arm/crtools.c | 8 ++----- arch/x86/crtools.c | 8 ++----- include/parasite-syscall.h | 6 ++--- parasite-syscall.c | 48 ++++++++++++++++++++++++-------------- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c index bbc5cf904..db02fce1f 100644 --- a/arch/arm/crtools.c +++ b/arch/arm/crtools.c @@ -73,14 +73,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, regs.ARM_r4 = arg5; regs.ARM_r5 = arg6; - parasite_setup_regs(ctl->syscall_ip, 0, ®s); - err = __parasite_execute_trap(ctl, ctl->pid.real, ®s, - &ctl->regs_orig, &ctl->sig_blocked); - if (err) - return err; + err = __parasite_execute_syscall(ctl, ®s); *ret = regs.ARM_r0; - return 0; + return err; } #define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))src.ARM_##e diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c index c8c94336b..474e73166 100644 --- a/arch/x86/crtools.c +++ b/arch/x86/crtools.c @@ -100,14 +100,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, regs.r8 = arg5; regs.r9 = arg6; - parasite_setup_regs(ctl->syscall_ip, 0, ®s); - err = __parasite_execute_trap(ctl, ctl->pid.real, ®s, - &ctl->regs_orig, &ctl->sig_blocked); - if (err) - return err; + err = __parasite_execute_syscall(ctl, ®s); *ret = regs.ax; - return 0; + return err; } int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index fb1236dda..45a1d635c 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -101,10 +101,8 @@ extern int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6); -extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid, - user_regs_struct_t *regs, - user_regs_struct_t *regs_orig, - k_rtsigset_t *sigmask); +extern int __parasite_execute_syscall(struct parasite_ctl *ctl, + user_regs_struct_t *regs); extern bool arch_can_dump_task(pid_t pid); extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid, diff --git a/parasite-syscall.c b/parasite-syscall.c index 07b45bc23..e8b690fe9 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -66,7 +66,7 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned } /* we run at @regs->ip */ -int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid, +static int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid, user_regs_struct_t *regs, user_regs_struct_t *regs_orig, k_rtsigset_t *sigmask) @@ -144,6 +144,35 @@ err_sigmask: return ret; } +int __parasite_execute_syscall(struct parasite_ctl *ctl, user_regs_struct_t *regs) +{ + pid_t pid = ctl->pid.real; + int err; + + /* + * Inject syscall instruction and remember original code, + * we will need it to restore original program content. + */ + memcpy(ctl->code_orig, code_syscall, sizeof(ctl->code_orig)); + if (ptrace_swap_area(pid, (void *)ctl->syscall_ip, + (void *)ctl->code_orig, sizeof(ctl->code_orig))) { + pr_err("Can't inject syscall blob (pid: %d)\n", pid); + return -1; + } + + parasite_setup_regs(ctl->syscall_ip, 0, regs); + err = __parasite_execute_trap(ctl, pid, regs, &ctl->regs_orig, + &ctl->sig_blocked); + + if (ptrace_poke_area(pid, (void *)ctl->code_orig, + (void *)ctl->syscall_ip, sizeof(ctl->code_orig))) { + pr_err("Can't restore syscall blob (pid: %d)\n", ctl->pid.real); + err = -1; + } + + return err; +} + void *parasite_args_s(struct parasite_ctl *ctl, int args_size) { BUG_ON(args_size > ctl->args_size); @@ -858,12 +887,6 @@ int parasite_cure_remote(struct parasite_ctl *ctl) } } - if (ptrace_poke_area(ctl->pid.real, (void *)ctl->code_orig, - (void *)ctl->syscall_ip, sizeof(ctl->code_orig))) { - pr_err("Can't restore syscall blob (pid: %d)\n", ctl->pid.real); - ret = -1; - } - return ret; } @@ -933,17 +956,6 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_ ctl->pid.virt = 0; ctl->syscall_ip = vma_area->vma.start; - /* - * Inject syscall instruction and remember original code, - * we will need it to restore original program content. - */ - memcpy(ctl->code_orig, code_syscall, sizeof(ctl->code_orig)); - if (ptrace_swap_area(pid, (void *)ctl->syscall_ip, - (void *)ctl->code_orig, sizeof(ctl->code_orig))) { - pr_err("Can't inject syscall blob (pid: %d)\n", pid); - goto err; - } - return ctl; err: