mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-18 00:58:31 +00:00
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=2561 Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
1abb8782a8
commit
a34057c192
3 changed files with 25 additions and 6 deletions
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue