[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