Commit a34057c1 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restore: add a synchronisation point after restoring credentials

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=2561Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 1abb8782
......@@ -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 */
......
......@@ -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
};
......
......@@ -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);
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment