mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 05:18:00 +00:00
parasite: modify process memory only for executing syscalls
Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
86a0777851
commit
f68f37a11f
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user