[CRIU] [PATCH 07/11] sk-unix: Fix path resolving for sockets with abs symlinks in paths
Cyrill Gorcunov
gorcunov at openvz.org
Tue Aug 2 08:34:33 PDT 2016
From: Cyrill Gorcunov <gorcunov at virtuozzo.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
---
criu/sk-unix.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 5 deletions(-)
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 2bab17faf434..4c716230af74 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -227,8 +227,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));
@@ -238,10 +239,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;
+ if (ret) {
+ if (errno_save == ENOENT)
continue;
+ pr_perror("Unable to stat %s", path);
goto err;
}
@@ -510,10 +519,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;
bool deleted = false;
+ 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);
@@ -550,11 +560,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;
}
@@ -568,6 +586,22 @@ static int unix_process_name(struct unix_sk_desc *d, const struct unix_diag_msg
name, (int)st.st_dev, (int)st.st_ino,
(int)uv->udiag_vfs_dev, (int)uv->udiag_vfs_ino);
deleted = true;
+ 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
+ * just drop his name, since no one will access
+ * it via one.
+ */
+ xfree(name);
+ len = 0;
+ name = NULL;
}
d->mode = st.st_mode;
--
2.7.4
More information about the CRIU
mailing list