[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