[CRIU] [PATCH] criu: fix segfault in pre-dump

Andrei Vagin avagin at virtuozzo.com
Wed Sep 12 02:16:23 MSK 2018


On Tue, Sep 11, 2018 at 09:51:15PM +0200, Adrian Reber wrote:
> From: Adrian Reber <areber at redhat.com>
> 
> By accident I found a segfault using pre-dump in combination with the
> page-server. Doing the following I was able to trigger it:
> 
>  * criu page-server -D /tmp/1
>  * criu pre-dump -t PID -D /tmp/3 --track-mem
>  * criu page-server -D /tmp/4 --prev-images-dir ../1
>  * criu pre-dump -t PID -D /tmp/3 --track-mem
>  --> segfault
> 
> ...
> (00.010090) Warn  (criu/image.c:134): Failed to open parent directory
> ...
> (00.012984) Error (criu/mem.c:318): Pid-reuse detection failed: no parent inventory, check warnings in get_parent_stats
> ...
> (00.013037) Error (criu/mem.c:544): Can't dump page with parasite
> ...
> (00.013955) Pre-dumping tasks' memory
> (00.013966) 	Pre-dumping 8793
> (00.014380) Transferring pages:
> Segmentation fault (core dumped)
> 
> Looking in cr-dump.c at cr_pre_dump_finish(int ret) the function gets
> the return code of the previous operations in 'ret' but it is
> immediately overwritten and never used.
> 
> In older CRIU versions it used to be:
> 
> 	if (ret < 0)
> 		goto err;
> 
> but that is gone now. So this reintroduces the check for the int
> parameter given to cr_pre_dump_finish() by the function caller.
> 
> As the commands used to trigged the segfault do not make much sense the
> result is still not usable and the same 'Warn' and 'Error' messages are
> printed, but the segfault is gone.
> 
> Signed-off-by: Adrian Reber <areber at redhat.com>
> ---
>  criu/cr-dump.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/cr-dump.c b/criu/cr-dump.c
> index ec5e1e45b..df31de1a9 100644
> --- a/criu/cr-dump.c
> +++ b/criu/cr-dump.c
> @@ -1474,10 +1474,11 @@ static int setup_alarm_handler()
>  	return 0;
>  }
>  
> -static int cr_pre_dump_finish(int ret)
> +static int cr_pre_dump_finish(int status)
>  {
>  	InventoryEntry he = INVENTORY_ENTRY__INIT;
>  	struct pstree_item *item;
> +	int ret;
>  
>  	/*
>  	 * Restore registers for tasks only. The threads have not been
> @@ -1495,6 +1496,9 @@ static int cr_pre_dump_finish(int ret)
>  
>  	timing_stop(TIME_FROZEN);
>  
> +	if (status < 0)

I think we need to set ret in this case

		ret = status;
> +		goto err;
> +
>  	pr_info("Pre-dumping tasks' memory\n");
>  	for_each_pstree_item(item) {
>  		struct parasite_ctl *ctl = dmpi(item)->parasite_ctl;
> -- 
> 2.17.1
> 


More information about the CRIU mailing list