[CRIU] [PATCH 2/2] sk-unix: Fix path resolving for sockets with abs symlinks in paths

Andrey Vagin avagin at virtuozzo.com
Wed Jun 8 00:03:43 PDT 2016


Actually we need to fix the same problem not only for unix sockets.

We need to check all places where we work with mntns_root.

On Tue, Jun 07, 2016 at 09:07:37PM +0300, Cyrill Gorcunov wrote:
> From: Cyrill Gorcunov <gorcunov at virtuozzo.com>
> 
> https://bugs.openvz.org/browse/OVZ-6747
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
> ---
>  criu/sk-unix.c | 31 ++++++++++++++++++++++++++-----
>  1 file changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/criu/sk-unix.c b/criu/sk-unix.c
> index 3363cea22cf8..69feadf7e36c 100644
> --- a/criu/sk-unix.c
> +++ b/criu/sk-unix.c
> @@ -226,8 +226,9 @@ static int resolve_rel_name(struct unix_sk_desc *sk, const struct fd_parms *p)
>  
>  	for (i = 0; i < ARRAY_SIZE(dirs); i++) {
>  		char dir[PATH_MAX], path[PATH_MAX];
> +		int ret, root_fd;
>  		struct stat st;
> -		int ret;
> +		int errno_save;
>  
>  		snprintf(path, sizeof(path), "/proc/%d/%s", p->pid, dirs[i]);
>  		ret = readlink(path, dir, sizeof(dir));
> @@ -237,10 +238,18 @@ static int resolve_rel_name(struct unix_sk_desc *sk, const struct fd_parms *p)
>  		}
>  		dir[ret] = 0;
>  
> +		if (cr_set_root(mntns_root, &root_fd))
> +			goto err;
> +
>  		snprintf(path, sizeof(path), ".%s/%s", dir, sk->name);
> -		if (fstatat(mntns_root, path, &st, 0)) {
> -			if (errno == ENOENT)
> +		ret = fstatat(mntns_root, path, &st, 0);
> +		errno_save = errno;
> +		if (cr_restore_root(root_fd))
> +			goto err;

I was talking with Pavel about this problem and we decided to not
restore root each time. We can do it only when it's requred. In this
case the overhead will be much smaller.

> +		if (ret) {
> +			if (errno_save == ENOENT)
>  				continue;
> +			pr_perror("Unable to stat %s", path);
>  			goto err;
>  		}
>  
> @@ -508,11 +517,11 @@ static int unix_process_name(struct unix_sk_desc *d, const struct unix_diag_msg
>  
>  	if (name[0] != '\0') {
>  		struct unix_diag_vfs *uv;
> +		int mntns_root, root_fd;
>  		bool drop_path = false;
>  		char rpath[PATH_MAX];
>  		struct ns_id *ns;
>  		struct stat st;
> -		int mntns_root;
>  
>  		if (!tb[UNIX_DIAG_VFS]) {
>  			pr_err("Bound socket w/o inode %#x\n", m->udiag_ino);
> @@ -549,11 +558,19 @@ static int unix_process_name(struct unix_sk_desc *d, const struct unix_diag_msg
>  			goto postprone;
>  		}
>  
> +		ret = cr_set_root(mntns_root, &root_fd);
> +		if (ret)
> +			goto out;
> +
>  		snprintf(rpath, sizeof(rpath), ".%s", name);
> -		if (fstatat(mntns_root, rpath, &st, 0)) {
> +		ret = fstatat(mntns_root, rpath, &st, 0);
> +		if (ret) {
>  			if (errno != ENOENT) {
>  				pr_warn("Can't stat socket %#x(%s), skipping: %m (err %d)\n",
>  					m->udiag_ino, rpath, errno);
> +				ret = cr_restore_root(root_fd);
> +				if (ret)
> +					goto out;
>  				goto skip;
>  			}
>  
> @@ -569,6 +586,10 @@ static int unix_process_name(struct unix_sk_desc *d, const struct unix_diag_msg
>  			drop_path = true;
>  		}
>  
> +		ret = cr_restore_root(root_fd);
> +		if (ret)
> +			goto out;
> +
>  		if (drop_path) {
>  			/*
>  			 * When a socket is bound to unlinked file, we
> -- 
> 2.5.5
> 


More information about the CRIU mailing list