[CRIU] [PATCH] creds: restore -- Honor rst_mem_alloc rules

Andrew Vagin avagin at virtuozzo.com
Thu Dec 24 12:10:56 PST 2015


On Thu, Dec 24, 2015 at 10:42:45PM +0300, Cyrill Gorcunov wrote:
> rst_mem_alloc rules might move previously allocated
> blocks which means we can't reuse previously allocated
> pointer if new block is created. Thus remember pointers
> positions where needed and adjust them accordingly.
> 
> https://github.com/xemul/criu/issues/97
>

Acked-by: Andrew Vagin <avagin at virtuozzo.com> 
> Reported-by: Andrew Vagin <avagin at virtuozzo.com>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  cr-restore.c | 33 ++++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/cr-restore.c b/cr-restore.c
> index 0166f1ca47f2..ba3cbe604ce6 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -2807,7 +2807,7 @@ static void rst_reloc_creds(struct thread_restore_args *thread_args,
>  }
>  
>  static struct thread_creds_args *
> -rst_prep_creds_args(struct thread_creds_args *prev, CredsEntry *ce)
> +rst_prep_creds_args(CredsEntry *ce, unsigned long *prev_pos)
>  {
>  	unsigned long this_pos = rst_mem_cpos(RM_PRIVATE);
>  	struct thread_creds_args *args;
> @@ -2839,18 +2839,21 @@ rst_prep_creds_args(struct thread_creds_args *prev, CredsEntry *ce)
>  
>  		if (profile) {
>  			size_t lsm_profile_len;
> +			char *lsm_profile;
>  
>  			if (render_lsm_profile(profile, &rendered))
>  				return ERR_PTR(-EINVAL);
>  
>  			args->mem_lsm_profile_pos = rst_mem_cpos(RM_PRIVATE);
>  			lsm_profile_len = strlen(rendered);
> -			args->lsm_profile = rst_mem_alloc(lsm_profile_len + 1, RM_PRIVATE);
> -			if (!args->lsm_profile) {
> +			lsm_profile = rst_mem_alloc(lsm_profile_len + 1, RM_PRIVATE);
> +			if (!lsm_profile) {
>  				xfree(rendered);
>  				return ERR_PTR(-ENOMEM);
>  			}
>  
> +			args = rst_mem_remap_ptr(this_pos, RM_PRIVATE);
> +			args->lsm_profile = lsm_profile;
>  			strncpy(args->lsm_profile, rendered, lsm_profile_len);
>  			xfree(rendered);
>  		}
> @@ -2875,10 +2878,14 @@ rst_prep_creds_args(struct thread_creds_args *prev, CredsEntry *ce)
>  	memcpy(args->cap_bnd, ce->cap_bnd, sizeof(args->cap_bnd));
>  
>  	if (ce->n_groups) {
> +		unsigned int *groups;
> +
>  		args->mem_groups_pos = rst_mem_cpos(RM_PRIVATE);
> -		args->groups = rst_mem_alloc(ce->n_groups * sizeof(u32), RM_PRIVATE);
> -		if (!args->groups)
> +		groups = rst_mem_alloc(ce->n_groups * sizeof(u32), RM_PRIVATE);
> +		if (!groups)
>  			return ERR_PTR(-ENOMEM);
> +		args = rst_mem_remap_ptr(this_pos, RM_PRIVATE);
> +		args->groups = groups;
>  		memcpy(args->groups, ce->groups, ce->n_groups * sizeof(u32));
>  	} else {
>  		args->groups = NULL;
> @@ -2887,8 +2894,15 @@ rst_prep_creds_args(struct thread_creds_args *prev, CredsEntry *ce)
>  
>  	args->mem_pos_next = 0;
>  
> -	if (prev)
> -		prev->mem_pos_next = this_pos;
> +	if (prev_pos) {
> +		if (*prev_pos) {
> +			struct thread_creds_args *prev;
> +
> +			prev = rst_mem_remap_ptr(*prev_pos, RM_PRIVATE);
> +			prev->mem_pos_next = this_pos;
> +		}
> +		*prev_pos = this_pos;
> +	}
>  	return args;
>  }
>  
> @@ -2908,7 +2922,7 @@ static int rst_prep_creds_from_img(pid_t pid)
>  	if (ret > 0) {
>  		struct thread_creds_args *args;
>  
> -		args = rst_prep_creds_args(NULL, ce);
> +		args = rst_prep_creds_args(ce, NULL);
>  		if (IS_ERR(args))
>  			ret = PTR_ERR(args);
>  		else
> @@ -2921,6 +2935,7 @@ static int rst_prep_creds_from_img(pid_t pid)
>  static int rst_prep_creds(pid_t pid, CoreEntry *core, unsigned long *creds_pos)
>  {
>  	struct thread_creds_args *args = NULL;
> +	unsigned long this_pos = 0;
>  	size_t i;
>  
>  	/*
> @@ -2946,7 +2961,7 @@ static int rst_prep_creds(pid_t pid, CoreEntry *core, unsigned long *creds_pos)
>  	for (i = 0; i < current->nr_threads; i++) {
>  		CredsEntry *ce = current->core[i]->thread_core->creds;
>  
> -		args = rst_prep_creds_args(args, ce);
> +		args = rst_prep_creds_args(ce, &this_pos);
>  		if (IS_ERR(args))
>  			return PTR_ERR(args);
>  	}
> -- 
> 2.5.0
> 


More information about the CRIU mailing list