[CRIU] Re: [PATCH] rst: Fix creds vs threads restoration
Andrey Vagin
avagin at parallels.com
Tue Oct 30 05:38:32 EDT 2012
On Tue, Oct 30, 2012 at 10:37:17AM +0400, Pavel Emelyanov wrote:
> Writing to last_pid sysctl is CAP_SYS_ADMIN potected. Thus restoring
> creds before it won't work in all the cases.
>
> Fix this by making all threads restore creds themselves, and the
> thread group leader -- after all of them.
>
> #2410
>
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
Probably we should drop CAP_SYS_ADMIN in zdtm tests (futex*, pthread*)
Acked-by: Andrey Vagin <avagin at parallels.com>
>
> ---
>
> diff --git a/cr-restore.c b/cr-restore.c
> index e930b49..d47e34f 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -1495,7 +1495,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
> if (ret < 0)
> goto err;
>
> - mutex_init(&task_args->t._rst_lock);
> + mutex_init(&task_args->rst_lock);
>
> /*
> * Now prepare run-time data for threads restore.
> @@ -1537,7 +1537,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
> goto err;
> }
>
> - thread_args[i].rst_lock = &task_args->t._rst_lock;
> + thread_args[i].ta = task_args;
> thread_args[i].gpregs = *core->thread_info->gpregs;
> thread_args[i].clear_tid_addr = core->thread_info->clear_tid_addr;
>
> diff --git a/include/restorer.h b/include/restorer.h
> index 7c74a29..11750e4 100644
> --- a/include/restorer.h
> +++ b/include/restorer.h
> @@ -62,6 +62,8 @@ struct rst_sched_param {
> int prio;
> };
>
> +struct task_restore_core_args;
> +
> /* Make sure it's pow2 in size */
> struct thread_restore_args {
> struct restore_mem_zone mem_zone;
> @@ -76,10 +78,7 @@ struct thread_restore_args {
>
> struct rst_sched_param sp;
>
> - union {
> - mutex_t _rst_lock;
> - mutex_t *rst_lock;
> - };
> + struct task_restore_core_args *ta;
> } __aligned(sizeof(long));
>
> struct task_restore_core_args {
> @@ -90,6 +89,8 @@ struct task_restore_core_args {
> int logfd;
> unsigned int loglevel;
>
> + mutex_t rst_lock;
> +
> /* threads restoration */
> int nr_threads; /* number of threads */
> thread_restore_fcall_t clone_restore_fn; /* helper address for clone() call */
> diff --git a/restorer.c b/restorer.c
> index 2dd3733..369adb9 100644
> --- a/restorer.c
> +++ b/restorer.c
> @@ -224,7 +224,9 @@ long __export_restore_thread(struct thread_restore_args *args)
> if (restore_thread_common(rt_sigframe, args))
> goto core_restore_end;
>
> - mutex_unlock(args->rst_lock);
> + mutex_unlock(&args->ta->rst_lock);
> +
> + restore_creds(&args->ta->creds);
>
> futex_dec_and_wake(&task_entries->nr_in_progress);
>
> @@ -529,14 +531,6 @@ long __export_restore_task(struct task_restore_core_args *args)
> goto core_restore_end;
> }
>
> - /*
> - * last-pid is CAP_SYS_ADMIN protected, thus restore creds
> - * _after_ opening that file, but before fork to make threads
> - * inherit them properly
> - */
> -
> - restore_creds(&args->creds);
> -
> ret = sys_flock(fd, LOCK_EX);
> if (ret) {
> pr_err("Can't lock last_pid %d\n", fd);
> @@ -550,7 +544,7 @@ long __export_restore_task(struct task_restore_core_args *args)
> if (thread_args[i].pid == args->t.pid)
> continue;
>
> - mutex_lock(&args->t._rst_lock);
> + mutex_lock(&args->rst_lock);
>
> new_sp =
> RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
> @@ -613,8 +607,14 @@ long __export_restore_task(struct task_restore_core_args *args)
> }
>
> sys_close(fd);
> - } else
> - restore_creds(&args->creds);
> + }
> +
> + /*
> + * Writing to last-pid is CAP_SYS_ADMIN protected, thus restore
> + * creds _after_ all threads creation.
> + */
> +
> + restore_creds(&args->creds);
>
> futex_dec_and_wake(&args->task_entries->nr_in_progress);
>
More information about the CRIU
mailing list