Commit 6e4d0585 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

compel: infect -- Don't forget to fetch sas early

When infecting victim we construct sigframe to
be able to self-rectore it in case if something
goes wrong. But in case is a targer been using
alternative stack for signal handling it will
be missed in sigframe since we don't fetch it.

Thus add fetching sas on infection stage and
put it into signal frame early.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent e5de8986
...@@ -140,6 +140,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) ...@@ -140,6 +140,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true; return true;
} }
int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
{
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->uc.uc_stack,
0, 0, 0, 0);
return err ? err : ret;
}
/* /*
* Range for task size calculated from the following Linux kernel files: * Range for task size calculated from the following Linux kernel files:
* arch/arm64/include/asm/memory.h * arch/arm64/include/asm/memory.h
......
...@@ -160,6 +160,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) ...@@ -160,6 +160,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true; return true;
} }
int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
{
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->sig.uc.uc_stack,
0, 0, 0, 0);
return err ? err : ret;
}
/* /*
* Range for task size calculated from the following Linux kernel files: * Range for task size calculated from the following Linux kernel files:
* arch/arm/include/asm/memory.h * arch/arm/include/asm/memory.h
......
...@@ -442,6 +442,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) ...@@ -442,6 +442,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true; return true;
} }
int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
{
long ret;
int err;
err = compel_syscall(ctl, __NR_sigaltstack,
&ret, 0, (unsigned long)&s->uc.uc_stack,
0, 0, 0, 0);
return err ? err : ret;
}
/* /*
* Copied for the Linux kernel arch/powerpc/include/asm/processor.h * Copied for the Linux kernel arch/powerpc/include/asm/processor.h
* *
......
...@@ -419,6 +419,21 @@ bool arch_can_dump_task(struct parasite_ctl *ctl) ...@@ -419,6 +419,21 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true; return true;
} }
int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s)
{
int native = compel_mode_native(ctl);
void *where = native ?
(void *)&s->native.uc.uc_stack :
(void *)&s->compat.uc.uc_stack;
long ret;
int err;
err = compel_syscall(ctl, __NR(sigaltstack, !native),
&ret, 0, (unsigned long)where,
0, 0, 0, 0);
return err ? err : ret;
}
/* Copied from the gdb header gdb/nat/x86-dregs.h */ /* Copied from the gdb header gdb/nat/x86-dregs.h */
/* Debug registers' indices. */ /* Debug registers' indices. */
......
...@@ -59,6 +59,7 @@ extern void *remote_mmap(struct parasite_ctl *ctl, ...@@ -59,6 +59,7 @@ extern void *remote_mmap(struct parasite_ctl *ctl,
int flags, int fd, off_t offset); int flags, int fd, off_t offset);
extern bool arch_can_dump_task(struct parasite_ctl *ctl); extern bool arch_can_dump_task(struct parasite_ctl *ctl);
extern int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, void *arg); extern int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, void *arg);
extern int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s);
extern int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe, extern int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
user_regs_struct_t *regs, user_regs_struct_t *regs,
user_fpregs_struct_t *fpregs); user_fpregs_struct_t *fpregs);
......
...@@ -894,6 +894,13 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l ...@@ -894,6 +894,13 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
ctl->r_thread_stack = ctl->remote_map + p; ctl->r_thread_stack = ctl->remote_map + p;
} }
ret = arch_fetch_sas(ctl, ctl->rsigframe);
if (ret) {
pr_err("Can't fetch sigaltstack for task %d (ret %d)",
ctl->rpid, ret);
goto err;
}
if (parasite_start_daemon(ctl)) if (parasite_start_daemon(ctl))
goto err; goto 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