[CRIU] [PATCH 6/9] parasite: add a function for unmaping bootstrap blob
Andrey Vagin
avagin at openvz.org
Thu Sep 12 09:24:38 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 baec7bb..02aee56 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -887,6 +887,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, ®s);
+ if (ptrace(PTRACE_SETREGS, pid, NULL, ®s)) {
+ 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;
+}
+
struct parasite_ctl *__parasite_prep_ctl(pid_t pid)
{
struct parasite_ctl *ctl = NULL;
--
1.8.3.1
More information about the CRIU
mailing list