[CRIU] [PATCH v2 18/30] files: Choose file master with enough permissions

Andrei Vagin avagin at virtuozzo.com
Thu Jun 15 09:32:48 MSK 2017


On Wed, Jun 07, 2017 at 02:28:53PM +0300, Kirill Tkhai wrote:
> 1)Find such fle, and link it at the beginning of list.
> 2)Order by pid, where possible, if it does not contradict (1)

Why do we need to order by pid?

> 3)If there is no a master, leave fdesc in fake_master_head.
> 
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
>  criu/files.c |   43 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/files.c b/criu/files.c
> index a46dcf330..a2b57ca01 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -84,6 +84,13 @@ int file_desc_add(struct file_desc *d, u32 id, struct file_desc_ops *ops)
>  	hlist_add_head(&d->hash, &file_desc_hash[id % FDESC_HASH_SIZE]);
>  	if (d->ops->get_user_ns) {
>  		d->ops->get_user_ns(d, &file_user_ns, &d->setns_userns);
> +		/*
> +		 * Hash file_desc in the fake_master_list. Later it will
> +		 * be removed in collect_desc_fle() from there, if a fle
> +		 * with enough permissions is found.
> +		 */
> +		if (d->setns_userns)
> +			list_add(&d->fake_master_list, &fake_master_head);
>  	}
>  	return 0; /* this is to make tail-calls in collect_one_foo look nice */
>  }
> @@ -717,12 +724,46 @@ static struct fdinfo_list_entry *alloc_fle(int pid, FdinfoEntry *fe)
>  static void collect_desc_fle(struct fdinfo_list_entry *new_le, struct file_desc *fdesc)
>  {
>  	struct fdinfo_list_entry *le;
> +	struct ns_id *task_ns = NULL;
> +	bool first = true;
>  
>  	new_le->desc = fdesc;
>  
> -	list_for_each_entry(le, &fdesc->fd_info_head, desc_list)
> +	/*
> +	 * First fle in fdesc->fd_info_head list (i.e., master)
> +	 * must have enough permissions to restore file.
> +	 * Sort the rest of list and cases by pid if it's possible.
> +	 */
> +	list_for_each_entry(le, &fdesc->fd_info_head, desc_list) {
> +		if (!fdesc->setns_userns || !first ||
> +		    le->task->ids->user_ns_id == new_le->task->ids->user_ns_id)
> +			goto compare_pid;
> +
> +		task_ns = lookup_ns_by_id(new_le->task->ids->user_ns_id, &user_ns_desc);
> +		if (is_subns(fdesc->setns_userns, task_ns))
> +			break;
> +		task_ns = NULL;
> +
> +		if (list_empty(&fdesc->fake_master_list)) {
> +			/* Current master has perms, leave it on the place */
> +			first = false;
> +			continue;
> +		}
> +compare_pid:
>  		if (pid_rst_prio(new_le->pid, le->pid))
>  			break;
> +		first = false;
> +	}
> +
> +	if (fdesc->setns_userns && list_empty(&fdesc->fd_info_head)) {
> +		/* First fle is hashing */
> +		task_ns = lookup_ns_by_id(new_le->task->ids->user_ns_id, &user_ns_desc);
> +		if (!is_subns(fdesc->setns_userns, task_ns))
> +			task_ns = NULL;
> +	}
> +	if (task_ns)
> +		list_del_init(&fdesc->fake_master_list);
> +
>  	list_add_tail(&new_le->desc_list, &le->desc_list);
>  }
>  
> 


More information about the CRIU mailing list