[CRIU] [PATCH] unix: wait for listen() as well as bind()

Andrew Vagin avagin at odin.com
Wed Jul 15 07:46:30 PDT 2015


On Wed, Jul 15, 2015 at 07:06:25AM -0600, Tycho Andersen wrote:
> We need to wait for listen() as well as bind() for internal unix sockets, or we
> can race like this:
> 
> (00.135950)      1: Opening standalone socket (id 0xb ino 0x9422f peer 0)
> (00.135974)    353: Error (sk-unix.c:701): Can't connect 0x947c4 socket: Connection refused
> (00.136390)      1: Error (cr-restore.c:1228): 353 exited, status=1
> (00.136407)      1:  Putting 0x9422f into listen state
> 
> (where 0x9422f is the peer for 0x947c4)
> 
> This race was pretty rare for me, but I've run 1000 tests and it didn't
> happen so hopefully this patch fixes it :)
>

Acked-by: Andrew Vagin <avagin at odin.com> 
> Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
> ---
>  sk-unix.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/sk-unix.c b/sk-unix.c
> index 2a4df85..6c9ec25 100644
> --- a/sk-unix.c
> +++ b/sk-unix.c
> @@ -631,7 +631,13 @@ struct unix_sk_info {
>  	unsigned flags;
>  	struct unix_sk_info *peer;
>  	struct file_desc d;
> -	futex_t bound;
> +
> +	/*
> +	 * Futex to signal when the socket is prepared. In particular, we
> +	 * signal after bind()ing the socket if it is not in TCP_LISTEN, or
> +	 * after listen() if the socket is in TCP_LISTEN.
> +	 */
> +	futex_t prepared;
>  };
>  
>  #define USK_PAIR_MASTER		0x1
> @@ -689,7 +695,7 @@ static int post_open_unix_sk(struct file_desc *d, int fd)
>  
>  	/* Skip external sockets */
>  	if (!list_empty(&peer->d.fd_info_head))
> -		futex_wait_while(&peer->bound, 0);
> +		futex_wait_while(&peer->prepared, 0);
>  
>  	memset(&addr, 0, sizeof(addr));
>  	addr.sun_family = AF_UNIX;
> @@ -764,7 +770,8 @@ static int bind_unix_sk(int sk, struct unix_sk_info *ui)
>  		}
>  	}
>  
> -	futex_set_and_wake(&ui->bound, 1);
> +	if (ui->ue->state != TCP_LISTEN)
> +		futex_set_and_wake(&ui->prepared, 1);
>  done:
>  	return 0;
>  }
> @@ -957,6 +964,7 @@ static int open_unixsk_standalone(struct unix_sk_info *ui)
>  			pr_perror("Can't make usk listen");
>  			return -1;
>  		}
> +		futex_set_and_wake(&ui->prepared, 1);
>  	}
>  out:
>  	if (rst_file_params(sk, ui->ue->fown, ui->ue->flags))
> @@ -1012,7 +1020,7 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base)
>  	} else
>  		ui->name = NULL;
>  
> -	futex_init(&ui->bound);
> +	futex_init(&ui->prepared);
>  	ui->peer = NULL;
>  	ui->flags = 0;
>  	pr_info(" `- Got %#x peer %#x (name %s)\n",
> -- 
> 2.1.4
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list