Commit f68f37a1 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

parasite: modify process memory only for executing syscalls

Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 86a07778
...@@ -73,14 +73,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -73,14 +73,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
regs.ARM_r4 = arg5; regs.ARM_r4 = arg5;
regs.ARM_r5 = arg6; regs.ARM_r5 = arg6;
parasite_setup_regs(ctl->syscall_ip, 0, &regs); err = __parasite_execute_syscall(ctl, &regs);
err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
&ctl->regs_orig, &ctl->sig_blocked);
if (err)
return err;
*ret = regs.ARM_r0; *ret = regs.ARM_r0;
return 0; return err;
} }
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))src.ARM_##e #define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))src.ARM_##e
......
...@@ -100,14 +100,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -100,14 +100,10 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
regs.r8 = arg5; regs.r8 = arg5;
regs.r9 = arg6; regs.r9 = arg6;
parasite_setup_regs(ctl->syscall_ip, 0, &regs); err = __parasite_execute_syscall(ctl, &regs);
err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
&ctl->regs_orig, &ctl->sig_blocked);
if (err)
return err;
*ret = regs.ax; *ret = regs.ax;
return 0; return err;
} }
int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core) int get_task_regs(pid_t pid, user_regs_struct_t regs, CoreEntry *core)
......
...@@ -101,10 +101,8 @@ extern int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -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 arg3, unsigned long arg4,
unsigned long arg5, unsigned long arg6); unsigned long arg5, unsigned long arg6);
extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid, extern int __parasite_execute_syscall(struct parasite_ctl *ctl,
user_regs_struct_t *regs, user_regs_struct_t *regs);
user_regs_struct_t *regs_orig,
k_rtsigset_t *sigmask);
extern bool arch_can_dump_task(pid_t pid); extern bool arch_can_dump_task(pid_t pid);
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid, extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
......
...@@ -66,7 +66,7 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned ...@@ -66,7 +66,7 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned
} }
/* we run at @regs->ip */ /* 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,
user_regs_struct_t *regs_orig, user_regs_struct_t *regs_orig,
k_rtsigset_t *sigmask) k_rtsigset_t *sigmask)
...@@ -144,6 +144,35 @@ err_sigmask: ...@@ -144,6 +144,35 @@ err_sigmask:
return ret; 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) void *parasite_args_s(struct parasite_ctl *ctl, int args_size)
{ {
BUG_ON(args_size > ctl->args_size); BUG_ON(args_size > ctl->args_size);
...@@ -858,12 +887,6 @@ int parasite_cure_remote(struct parasite_ctl *ctl) ...@@ -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; return ret;
} }
...@@ -933,17 +956,6 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_ ...@@ -933,17 +956,6 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_
ctl->pid.virt = 0; ctl->pid.virt = 0;
ctl->syscall_ip = vma_area->vma.start; 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; return ctl;
err: err:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment