[CRIU] [PATCH] restore: add a synchronisation point after restoring credentials
Andrey Vagin
avagin at openvz.org
Thu Apr 18 06:14:41 EDT 2013
For security reason processes can be resumed only when all
credentials are restored. Otherwise someone can attach to a
process, which are not restored credentials yet and execute
some code.
https://bugzilla.openvz.org/show_bug.cgi?id=2561
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 9 ++++++++-
include/restorer.h | 7 +++++++
pie/restorer.c | 15 ++++++++++-----
3 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 0b9d601..f1cb706 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1159,6 +1159,8 @@ static inline int stage_participants(int next_stage)
case CR_STATE_RESTORE:
case CR_STATE_RESTORE_SIGCHLD:
return task_entries->nr_threads;
+ case CR_STATE_RESTORE_CREDS:
+ return task_entries->nr_threads;
}
BUG();
@@ -1239,11 +1241,16 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
if (ret < 0)
goto out;
- pr_info("Wait until all tasks are restored\n");
+ pr_info("Wait until all tasks restored sigchld handlers\n");
ret = restore_switch_stage(CR_STATE_RESTORE_SIGCHLD);
if (ret < 0)
goto out;
+ pr_info("Wait until all tasks are restored\n");
+ ret = restore_switch_stage(CR_STATE_RESTORE_CREDS);
+ if (ret < 0)
+ goto out;
+
futex_wait_until(&task_entries->nr_in_progress, 0);
/* Restore SIGCHLD here to skip SIGCHLD from a network sctip */
diff --git a/include/restorer.h b/include/restorer.h
index 842cc5e..ef19d64 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -164,6 +164,13 @@ enum {
CR_STATE_RESTORE_PGID,
CR_STATE_RESTORE,
CR_STATE_RESTORE_SIGCHLD,
+ /*
+ * For security reason processes can be resumed only when all
+ * credentials are restored. Otherwise someone can attach to a
+ * process, which are not restored credentials yet and execute
+ * some code.
+ */
+ CR_STATE_RESTORE_CREDS,
CR_STATE_COMPLETE
};
diff --git a/pie/restorer.c b/pie/restorer.c
index 7cd7372..4feea0c 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -53,6 +53,8 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
sys_getpid(), siginfo->si_pid, siginfo->si_pid);
futex_dec_and_wake(&task_entries->nr_in_progress);
futex_dec_and_wake(&zombies_inprogress);
+ task_entries->nr_threads--;
+ task_entries->nr_tasks--;
mutex_unlock(&task_entries->zombie_lock);
return;
}
@@ -264,6 +266,7 @@ long __export_restore_thread(struct thread_restore_args *args)
goto core_restore_end;
restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);
+ restore_finish_stage(CR_STATE_RESTORE_CREDS);
futex_dec_and_wake(&thread_inprogress);
new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
@@ -757,13 +760,8 @@ long __export_restore_task(struct task_restore_core_args *args)
if (ret)
goto core_restore_end;
- futex_set_and_wake(&thread_inprogress, args->nr_threads);
-
restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);
- /* Wait until children stop to use args->task_entries */
- futex_wait_while_gt(&thread_inprogress, 1);
-
if (args->siginfo_size) {
ret = sys_munmap(args->siginfo, args->siginfo_size);
if (ret < 0) {
@@ -782,6 +780,13 @@ long __export_restore_task(struct task_restore_core_args *args)
restore_creds(&args->creds);
+ futex_set_and_wake(&thread_inprogress, args->nr_threads);
+
+ restore_finish_stage(CR_STATE_RESTORE_CREDS);
+
+ /* Wait until children stop to use args->task_entries */
+ futex_wait_while_gt(&thread_inprogress, 1);
+
log_set_fd(-1);
/*
--
1.8.2
More information about the CRIU
mailing list