Commit 2c76fc8a authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

infect: Keep entry point for first syscall on ictx

This is the address of an executable VMA. To get one
we need to parse /proc/pid/maps, compel will do it, but
since criu already parses this file (to dump task vmas),
we can provide the address via ictx.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent c0e468dd
......@@ -166,12 +166,14 @@ int cr_exec(int pid, char **opt)
goto out_unseize;
}
ctl = parasite_prep_ctl(pid, p_start);
ctl = parasite_prep_ctl(pid);
if (!ctl) {
pr_err("Can't prep ctl %d\n", pid);
goto out_unseize;
}
ctl->ictx.syscall_ip = p_start;
si = find_syscall(sys_name, ctl);
if (!si) {
pr_err("Unknown syscall [%s]\n", sys_name);
......
......@@ -1654,7 +1654,7 @@ static void finalize_restore(void)
continue;
/* Unmap the restorer blob */
ctl = parasite_prep_ctl(pid, 0);
ctl = parasite_prep_ctl(pid);
if (ctl == NULL)
continue;
......
......@@ -37,6 +37,7 @@ struct infect_ctx {
int (*make_sigframe)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
void *regs_arg;
unsigned long syscall_ip; /* entry point of infection */
unsigned long flags; /* fine-tune (e.g. faults) */
void (*child_handler)(int, siginfo_t *, void *); /* hander for SIGCHLD deaths */
......@@ -67,7 +68,6 @@ struct parasite_ctl {
void *r_thread_stack; /* stack for non-leader threads */
unsigned long parasite_ip; /* service routine start ip */
unsigned long syscall_ip; /* entry point of infection */
unsigned int *addr_cmd; /* addr for command */
void *addr_args; /* address for arguments */
......@@ -122,7 +122,7 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
struct vm_area_list *vma_area_list);
extern void parasite_ensure_args_size(unsigned long sz);
extern unsigned long get_exec_start(struct vm_area_list *);
extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start);
extern struct parasite_ctl *parasite_prep_ctl(pid_t pid);
extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
extern int parasite_dump_cgroup(struct parasite_ctl *ctl, struct parasite_dump_cgroup_args *cgroup);
......
......@@ -224,18 +224,18 @@ int __parasite_execute_syscall(struct parasite_ctl *ctl,
* we will need it to restore original program content.
*/
memcpy(code_orig, code_syscall, sizeof(code_orig));
if (ptrace_swap_area(pid, (void *)ctl->syscall_ip,
if (ptrace_swap_area(pid, (void *)ctl->ictx.syscall_ip,
(void *)code_orig, sizeof(code_orig))) {
pr_err("Can't inject syscall blob (pid: %d)\n", pid);
return -1;
}
err = parasite_run(pid, PTRACE_CONT, ctl->syscall_ip, 0, regs, &ctl->orig);
err = parasite_run(pid, PTRACE_CONT, ctl->ictx.syscall_ip, 0, regs, &ctl->orig);
if (!err)
err = parasite_trap(ctl, pid, regs, &ctl->orig);
if (ptrace_poke_area(pid, (void *)code_orig,
(void *)ctl->syscall_ip, sizeof(code_orig))) {
(void *)ctl->ictx.syscall_ip, sizeof(code_orig))) {
pr_err("Can't restore syscall blob (pid: %d)\n", ctl->rpid);
err = -1;
}
......@@ -1244,7 +1244,7 @@ err:
}
/* If vma_area_list is NULL, a place for injecting syscall will not be set. */
struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start)
struct parasite_ctl *parasite_prep_ctl(pid_t pid)
{
struct parasite_ctl *ctl = NULL;
......@@ -1266,9 +1266,6 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start)
BUILD_BUG_ON(PARASITE_START_AREA_MIN < BUILTIN_SYSCALL_SIZE + MEMFD_FNAME_SZ);
ctl->syscall_ip = exec_start;
pr_debug("Parasite syscall_ip at %p\n", (void *)ctl->syscall_ip);
return ctl;
err:
......@@ -1310,7 +1307,7 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
{
void *where = (void *)ctl->syscall_ip + BUILTIN_SYSCALL_SIZE;
void *where = (void *)ctl->ictx.syscall_ip + BUILTIN_SYSCALL_SIZE;
u8 orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
pid_t pid = ctl->rpid;
unsigned long sret = -ENOSYS;
......@@ -1482,7 +1479,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
return NULL;
}
ctl = parasite_prep_ctl(pid, p);
ctl = parasite_prep_ctl(pid);
if (!ctl)
return NULL;
......@@ -1491,6 +1488,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
ctl->ictx.save_regs = save_task_regs;
ctl->ictx.make_sigframe = make_sigframe;
ctl->ictx.regs_arg = item->core[0];
ctl->ictx.syscall_ip = p;
pr_debug("Parasite syscall_ip at %#lx\n", p);
if (fault_injected(FI_NO_MEMFD))
ctl->ictx.flags |= INFECT_NO_MEMFD;
......
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