[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