[CRIU] [PATCH v2] compel: infect -- Don't forget to fetch sas early
Pavel Emelyanov
xemul at virtuozzo.com
Mon Feb 20 00:40:19 PST 2017
On 02/20/2017 11:33 AM, Cyrill Gorcunov wrote:
> 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.
The ciru/pie/parasite.c should stop calling sigaltstack itself
and get the sas from compel :)
-- Pavel
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> compel/arch/aarch64/src/lib/infect.c | 11 +++++++++++
> compel/arch/arm/src/lib/infect.c | 11 +++++++++++
> compel/arch/ppc64/src/lib/infect.c | 11 +++++++++++
> compel/arch/x86/src/lib/infect.c | 15 +++++++++++++++
> compel/include/infect-priv.h | 1 +
> compel/src/lib/infect.c | 7 +++++++
> 6 files changed, 56 insertions(+)
>
> diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c
> index 4f5534b75530..9a0fad205dfa 100644
> --- a/compel/arch/aarch64/src/lib/infect.c
> +++ b/compel/arch/aarch64/src/lib/infect.c
> @@ -140,6 +140,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
> 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:
> * arch/arm64/include/asm/memory.h
> diff --git a/compel/arch/arm/src/lib/infect.c b/compel/arch/arm/src/lib/infect.c
> index ad085ff98e07..be7103557217 100644
> --- a/compel/arch/arm/src/lib/infect.c
> +++ b/compel/arch/arm/src/lib/infect.c
> @@ -160,6 +160,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
> 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:
> * arch/arm/include/asm/memory.h
> diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c
> index 11154d6580fd..868e12da8e0a 100644
> --- a/compel/arch/ppc64/src/lib/infect.c
> +++ b/compel/arch/ppc64/src/lib/infect.c
> @@ -442,6 +442,17 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
> 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
> *
> diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c
> index f1b216650ec0..ef617cc76798 100644
> --- a/compel/arch/x86/src/lib/infect.c
> +++ b/compel/arch/x86/src/lib/infect.c
> @@ -419,6 +419,21 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
> 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 */
>
> /* Debug registers' indices. */
> diff --git a/compel/include/infect-priv.h b/compel/include/infect-priv.h
> index cf0ce3a927fb..cac1bee328b6 100644
> --- a/compel/include/infect-priv.h
> +++ b/compel/include/infect-priv.h
> @@ -58,6 +58,7 @@ extern void *remote_mmap(struct parasite_ctl *ctl,
> void *addr, size_t length, int prot,
> int flags, int fd, off_t offset);
> extern bool arch_can_dump_task(struct parasite_ctl *ctl);
> +extern int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s);
> extern int get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg);
> extern int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
> user_regs_struct_t *regs,
> diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
> index 78c9655efb7b..b3dea5cf1f6b 100644
> --- a/compel/src/lib/infect.c
> +++ b/compel/src/lib/infect.c
> @@ -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;
> }
>
> + 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))
> goto err;
>
>
More information about the CRIU
mailing list