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

Cyrill Gorcunov gorcunov at openvz.org
Sun Feb 19 14:18:15 PST 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 4f5534b75530..f07eafb1bf4f 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, &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..945cc361ec50 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, &s->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..7de9100e3b70 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, &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;
 
-- 
2.7.4



More information about the CRIU mailing list