[CRIU] [PATCH 06/15] parasite: add a function for unmaping bootstrap blob
Andrey Vagin
avagin at openvz.org
Mon Sep 23 06:33:29 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, 47 insertions(+), 1 deletion(-)
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 3515a30..2f4ca82 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -115,4 +115,5 @@ extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
struct vm_area_list *vma_area_list);
extern int parasite_stop_on_syscall(int tasks, int sys_nr);
+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 8be6e5e..48d0785 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -886,8 +886,53 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
}
/*
- * If vma_area_list is NULL, a place for injecting syscall will not be set.
+ * 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;
+}
+
+/* If vma_area_list is NULL, a place for injecting syscall will not be set. */
struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list)
{
struct parasite_ctl *ctl = NULL;
--
1.8.3.1
More information about the CRIU
mailing list