[CRIU] [PATCH 5/8] parasite: add a function for unmaping bootstrap blob

Andrey Vagin avagin at openvz.org
Fri Sep 13 05:53:42 EDT 2013


The munmap syscall must be executed from a process memory. The code can
be injected in memory and then removed. But we can avoid all these
actions, if the code will be in the blob and a process will be trapped
on the exit from the munmap syscall.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 include/parasite-syscall.h |  1 +
 parasite-syscall.c         | 47 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index cb07cb0..61856b5 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -116,4 +116,5 @@ extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 
 extern int parasite_stop_on_syscall(int tasks, int sys_nr);
 extern struct parasite_ctl *__parasite_prep_ctl(pid_t pid);
+extern int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr);
 #endif /* __CR_PARASITE_SYSCALL_H__ */
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 65b380b..9fa7276 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -881,6 +881,53 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
 	return ret;
 }
 
+/*
+ * parasite_unmap() is used for unmapping parasite and restorer blobs.
+ * A blob can contain code for unmapping itself, so the porcess is
+ * trapped on the exit from the munmap syscall.
+ */
+int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr)
+{
+	user_regs_struct_t regs;
+	pid_t pid = ctl->pid.real;
+	k_rtsigset_t block;
+	int ret = -1;
+
+	ksigfillset(&block);
+
+	if (ptrace(PTRACE_SETSIGMASK, pid, sizeof(k_rtsigset_t), &block)) {
+		pr_perror("Can't block signals for %d", pid);
+		goto err;
+	}
+
+	regs = ctl->regs_orig;
+	parasite_setup_regs(addr, 0, &regs);
+	if (ptrace(PTRACE_SETREGS, pid, NULL, &regs)) {
+		pr_perror("Can't set registers for %d", pid);
+		goto err_sig;
+	}
+
+	if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL)) {
+		pr_perror("ptrace");
+		goto err_regs;
+	}
+
+	ret = parasite_stop_on_syscall(1, __NR_munmap);
+
+err_regs:
+	if (ptrace(PTRACE_SETREGS, pid, NULL, &ctl->regs_orig)) {
+		pr_perror("Can't restore regs for %d", pid);
+		ret = -1;
+	}
+err_sig:
+	if (ptrace(PTRACE_SETSIGMASK, pid, sizeof(k_rtsigset_t), &ctl->sig_blocked)) {
+		pr_perror("Can't restore sigmask for %d", pid);
+		ret = -1;
+	}
+err:
+	return ret;
+}
+
 /* __parasite_prep_ctl() doesn't search a place for injecting code */
 struct parasite_ctl *__parasite_prep_ctl(pid_t pid)
 {
-- 
1.8.3.1



More information about the CRIU mailing list