[CRIU] [PATCH 1/7] compel: infect -- Don't forget to fetch sas early

Cyrill Gorcunov gorcunov at openvz.org
Mon Mar 13 09:52:13 PDT 2017


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: 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 41600e0914ef..166ec2363b63 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 a78108dff30f..27d258bc3e0c 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 f3f1aacec854..32175174be89 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 84ff21b15729..23a96df86795 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 0f80895a7be8..00671e71fed9 100644
--- a/compel/include/infect-priv.h
+++ b/compel/include/infect-priv.h
@@ -59,6 +59,7 @@ extern void *remote_mmap(struct parasite_ctl *ctl,
 		int flags, int fd, off_t offset);
 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 arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s);
 extern int sigreturn_prep_regs_plain(struct rt_sigframe *sigframe,
 				     user_regs_struct_t *regs,
 				     user_fpregs_struct_t *fpregs);
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index c02425036e63..c34452fd6f12 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;
 
-- 
2.7.4



More information about the CRIU mailing list