[CRIU] [PATCH 7/9] parasite: block signals for each parasite command

Andrey Vagin avagin at openvz.org
Fri Jun 21 00:01:13 EDT 2013


Pending signals should be saved, so signals should be blocked.
Signals are blocked for EACH command, because a chance to corrupt a
process state should be so small as possible.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-exec.c                  |  2 +-
 include/parasite-syscall.h |  2 +-
 parasite-syscall.c         | 33 +++++++++++++++++++++++++++++++--
 3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/cr-exec.c b/cr-exec.c
index 1bf616b..5e86825 100644
--- a/cr-exec.c
+++ b/cr-exec.c
@@ -50,7 +50,7 @@ static int execute_syscall(struct parasite_ctl *ctl,
 			int len;
 
 			if (!r_mem) {
-				err = parasite_map_exchange(ctl, PAGE_SIZE);
+				err = parasite_map_exchange(ctl, PAGE_SIZE, NULL);
 				if (err)
 					return err;
 
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 9b6937a..587027f 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -86,7 +86,7 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
 						   struct parasite_drain_fd *dfds);
 extern struct parasite_ctl *parasite_prep_ctl(pid_t pid,
 					      struct vm_area_list *vma_area_list);
-extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
+extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size, k_rtsigset_t *mask);
 
 extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd);
 
diff --git a/parasite-syscall.c b/parasite-syscall.c
index ed28b30..bcbcf6b 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -998,13 +998,30 @@ err:
 	return NULL;
 }
 
-int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size)
+int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size, k_rtsigset_t *sigmask)
 {
 	int fd;
+	k_rtsigset_t blockall;
+	ksigfillset(&blockall);
+
+	if (sigmask) {
+		if (ptrace(PTRACE_SETSIGMASK, ctl->pid.real, sizeof(k_rtsigset_t), &blockall)) {
+			pr_perror("Unable to block signals\n");
+			return -1;
+		}
+	}
 
 	ctl->remote_map = mmap_seized(ctl, NULL, size,
 				      PROT_READ | PROT_WRITE | PROT_EXEC,
 				      MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+
+	if (sigmask) {
+		if (ptrace(PTRACE_SETSIGMASK, ctl->pid.real, sizeof(k_rtsigset_t), sigmask)) {
+			pr_perror("Unable to block signals\n");
+			return -1;
+		}
+	}
+
 	if (!ctl->remote_map) {
 		pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->pid.real);
 		return -1;
@@ -1082,6 +1099,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	int ret;
 	struct parasite_ctl *ctl;
 	unsigned long p, map_exchange_size;
+	k_rtsigset_t *sigmask;
 
 	BUG_ON(item->threads[0].real != pid);
 
@@ -1104,7 +1122,18 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE;
 	if (item->nr_threads > 1)
 		map_exchange_size += PARASITE_STACK_SIZE;
-	ret = parasite_map_exchange(ctl, map_exchange_size);
+
+	ret = ptrace(PTRACE_GETSIGMASK, pid, sizeof(k_rtsigset_t),
+		&item->core[0]->tc->blk_sigset);
+	if (ret == -1) {
+		pr_perror("ptrace doesn't support PTRACE_GETSIGMASK\n");
+		sigmask = 0;
+	} else {
+		ctl->use_sig_blocked = 1;
+		sigmask = (k_rtsigset_t *) &item->core[0]->tc->blk_sigset;
+	}
+
+	ret = parasite_map_exchange(ctl, map_exchange_size, sigmask);
 	if (ret)
 		goto err_restore;
 
-- 
1.8.2.1



More information about the CRIU mailing list