[CRIU] [PATCH 08/10] seccomp: Dont forget to suspend filtering on threads

Andrey Vagin avagin at virtuozzo.com
Wed May 16 03:10:13 MSK 2018


On Mon, May 07, 2018 at 11:42:48AM +0300, Cyrill Gorcunov wrote:
> When considering if we to call PTRACE_O_SUSPEND_SECCOMP
> on the tid we should take into account if there at least
> one thread which has seccomp mode enabled, otherwise
> we might miss filter suspension and restore procedure
> might break due to own criu syscall get filtered out.
> 
> Same time we should move seccomp restore for threads
> to take place after CR_STATE_RESTORE_SIGCHLD state
> so that main criu code will attach to threads and
> setup seccomp suspension flag before we start
> restoring the filters.
> 
> Reported-by: Andrei Vagin <avagin at virtuozzo.com>
> Reviewed-by: Dmitry Safonov <0x7f454c46 at gmail.com>
> Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
> ---
>  criu/cr-restore.c   | 29 +++++++++++++++++++++++++----
>  criu/pie/restorer.c | 21 ++++++++++-----------
>  2 files changed, 35 insertions(+), 15 deletions(-)
> 
> diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> index a7a232b2e028..89d73e191e97 100644
> --- a/criu/cr-restore.c
> +++ b/criu/cr-restore.c
> @@ -914,6 +914,23 @@ static int open_cores(int pid, CoreEntry *leader_core)
>  
>  	current->core = cores;
>  
> +	/*
> +	 * Walk over all threads and if one them is having
> +	 * active seccomp mode we will suspend filtering
> +	 * on the whole group until restore complete.
> +	 *
> +	 * Otherwise any criu code which might use same syscall
> +	 * if present inside a filter chain would take filter
> +	 * action and might break restore procedure.
> +	 */
> +	for (i = 0; i < current->nr_threads; i++) {
> +		ThreadCoreEntry *thread_core = cores[i]->thread_core;
> +		if (thread_core->seccomp_mode != SECCOMP_MODE_DISABLED) {
> +			rsti(current)->has_seccomp = true;
> +			break;
> +		}
> +	}
> +
>  	return 0;
>  err:
>  	xfree(cores);
> @@ -1531,10 +1548,14 @@ static inline int fork_with_pid(struct pstree_item *item)
>  			return -1;
>  		}
>  
> -		if (item->pid->state != TASK_DEAD)
> -			rsti(item)->has_seccomp = ca.core->thread_core->seccomp_mode != SECCOMP_MODE_DISABLED;
> -		else
> -			rsti(item)->has_seccomp = false;
> +		/*
> +		 * By default we assume that seccomp is not
> +		 * used at all (especially on dead task). Later
> +		 * we will walk over all threads and check in
> +		 * details if filter is present setting up
> +		 * this flag as appropriate.
> +		 */
> +		rsti(item)->has_seccomp = false;
>  
>  		if (unlikely(item == root_item))
>  			maybe_clone_parent(item, &ca);
> diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
> index 2ba0bcf2f72f..44f8648319e1 100644
> --- a/criu/pie/restorer.c
> +++ b/criu/pie/restorer.c
> @@ -574,17 +574,6 @@ long __export_restore_thread(struct thread_restore_args *args)
>  		sys_close(fd);
>  	}
>  
> -	/*
> -	 * Make sure it's before creds, since it's privileged
> -	 * operation bound to uid 0 in current user ns.
> -	 */
> -	if (restore_seccomp(args))
> -		goto core_restore_end;
> -
> -	ret = restore_creds(args->creds_args, args->ta->proc_fd);
> -	if (ret)
> -		goto core_restore_end;
> -
>  	ret = restore_dumpable_flag(&args->ta->mm);
>  	if (ret)
>  		goto core_restore_end;
> @@ -599,6 +588,16 @@ long __export_restore_thread(struct thread_restore_args *args)
>  	restore_finish_stage(task_entries_local, CR_STATE_RESTORE_SIGCHLD);
>  	restore_pdeath_sig(args);
>  
> +	/*
> +	 * Make sure it's before creds, since it's privileged
> +	 * operation bound to uid 0 in current user ns.
> +	 */
> +	if (restore_seccomp(args))
> +		goto core_restore_end;

I far as I remember, we can't call exit after CR_STATE_RESTORE_SIGCHLD,
I mean we can't use goto core_restore_end here

> +
> +	ret = restore_creds(args->creds_args, args->ta->proc_fd);
> +	if (ret)
> +		goto core_restore_end;
>  	restore_finish_stage(task_entries_local, CR_STATE_RESTORE_CREDS);
>  
>  	futex_dec_and_wake(&thread_inprogress);
> -- 
> 2.14.3
> 


More information about the CRIU mailing list