[CRIU] [PATCHv2] dump: preserve the dumpable flag on criu dump/restore

Andrew Vagin avagin at parallels.com
Tue Jun 17 02:33:44 PDT 2014


On Tue, May 13, 2014 at 09:00:16AM -0700, Filipe Brandenburger wrote:
> Preserve the dumpable flag, which affects whether a core dump will be
> generated, but also affects the ownership of the virtual files under
> /proc/$pid after restoring a process.
> 
> Tested: Restored a process with a criu including this patch and looked
> at /proc/$pid to confirm that the virtual files were no longer all owned
> by root:root.
> 
> zdtm tests pass except for cow01 which seems to be broken.
> (see https://bugzilla.openvz.org/show_bug.cgi?id=2967 for details.)
> 
> This patch fixes https://bugzilla.openvz.org/show_bug.cgi?id=2968
> 
> Signed-off-by: Filipe Brandenburger <filbranden at google.com>
> Change-Id: I8c386508448a84368a86666f2d7500b252a78bbf
> ---
>  cr-dump.c          |  3 +++
>  include/parasite.h |  2 ++
>  include/prctl.h    |  6 ++++++
>  pie/parasite.c     |  1 +
>  pie/restorer.c     | 21 +++++++++++++++++++++
>  protobuf/mm.proto  |  2 ++
>  6 files changed, 35 insertions(+)
> 
> diff --git a/cr-dump.c b/cr-dump.c
> index a4100c1c40f1..9683a4ef5faf 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -455,6 +455,9 @@ static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat,
>  
>  	mme.mm_brk = misc->brk;
>  
> +	mme.dumpable = misc->dumpable;
> +	mme.has_dumpable = true;
> +
>  	mme.n_mm_saved_auxv = AT_VECTOR_SIZE;
>  	mme.mm_saved_auxv = xmalloc(pb_repeated_size(&mme, mm_saved_auxv));
>  	if (!mme.mm_saved_auxv)
> diff --git a/include/parasite.h b/include/parasite.h
> index dd14da57c07e..9041ac842276 100644
> --- a/include/parasite.h
> +++ b/include/parasite.h
> @@ -157,6 +157,8 @@ struct parasite_dump_misc {
>  
>  	struct parasite_dump_thread	ti;
>  	u64 cycles;
> +
> +	int dumpable;
>  };
>  
>  #define PARASITE_MAX_GROUPS	(PAGE_SIZE / sizeof(unsigned int) - 2 * sizeof(unsigned))
> diff --git a/include/prctl.h b/include/prctl.h
> index 79fcb3529e26..9815c9f3ac3d 100644
> --- a/include/prctl.h
> +++ b/include/prctl.h
> @@ -16,6 +16,12 @@
>  #ifndef PR_SET_SECUREBITS
>  # define PR_SET_SECUREBITS	28
>  #endif
> +#ifndef PR_GET_DUMPABLE
> +# define PR_GET_DUMPABLE	3
> +#endif
> +#ifndef PR_SET_DUMPABLE
> +# define PR_SET_DUMPABLE	4
> +#endif
>  
>  #ifndef PR_SET_MM
>  #define PR_SET_MM		35
> diff --git a/pie/parasite.c b/pie/parasite.c
> index 5f13191fdad8..0c30603610ec 100644
> --- a/pie/parasite.c
> +++ b/pie/parasite.c
> @@ -163,6 +163,7 @@ static int dump_misc(struct parasite_dump_misc *args)
>  	args->umask = sys_umask(0);
>  	sys_umask(args->umask); /* never fails */
>  	args->cycles = arch_read_cycles();
> +	args->dumpable = sys_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
>  
>  	return dump_thread_common(&args->ti);
>  }
> diff --git a/pie/restorer.c b/pie/restorer.c
> index ac8013971029..c8bf073f20f1 100644
> --- a/pie/restorer.c
> +++ b/pie/restorer.c
> @@ -30,6 +30,7 @@
>  #include "restorer.h"
>  
>  #include "protobuf/creds.pb-c.h"
> +#include "protobuf/mm.pb-c.h"
>  
>  #include "asm/restorer.h"
>  #include "asm/cycles.h"
> @@ -188,6 +189,21 @@ static int restore_creds(CredsEntry *ce)
>  	return 0;
>  }
>  
> +static int restore_dumpable_flag(MmEntry *mme)
> +{
> +	int ret;
> +
> +	if (mme->has_dumpable) {
> +		ret = sys_prctl(PR_SET_DUMPABLE, mme->dumpable, 0, 0, 0);

prctl((PR_SET_DUMPABLE, 2) always fails. Filipe, do you want to
investigate how to handle this situation?

Thanks.

man 2 prctl:
...
In kernels  up  to  and  including  2.6.12,  arg2  must be either 0
(process is not dumpable) or 1 (process is  dumpable).   Between
kernels 2.6.13 and 2.6.17, the value 2 was also permitted, which
caused any binary which normally  would  not  be  dumped  to  be
dumped readable by root only; for security reasons, this feature
has   been   removed.
...

> +		if (ret) {
> +			pr_err("Unable to set PR_SET_DUMPABLE: %d\n", ret);
> +			return -1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static void restore_sched_info(struct rst_sched_param *p)
>  {
>  	struct sched_param parm;
> @@ -296,6 +312,10 @@ long __export_restore_thread(struct thread_restore_args *args)
>  	if (ret)
>  		goto core_restore_end;
>  
> +	ret = restore_dumpable_flag(&args->ta->mm);
> +	if (ret)
> +		goto core_restore_end;
> +
>  	pr_info("%ld: Restored\n", sys_gettid());
>  
>  	restore_finish_stage(CR_STATE_RESTORE);
> @@ -930,6 +950,7 @@ long __export_restore_task(struct task_restore_args *args)
>  	 */
>  
>  	ret = restore_creds(&args->creds);
> +	ret = ret || restore_dumpable_flag(&args->mm);
>  
>  	futex_set_and_wake(&thread_inprogress, args->nr_threads);
>  
> diff --git a/protobuf/mm.proto b/protobuf/mm.proto
> index b809061afdd1..1556b602d588 100644
> --- a/protobuf/mm.proto
> +++ b/protobuf/mm.proto
> @@ -17,4 +17,6 @@ message mm_entry {
>  	repeated uint64	mm_saved_auxv	= 13;
>  
>  	repeated vma_entry vmas		= 14;
> +
> +	optional int32	dumpable	= 15;
>  }
> -- 
> 1.9.1.423.g4596e3a
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list