From 1dce09bb142b6e9e89fbf4a5bcfc630b6ffa9ee7 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Fri, 5 May 2017 19:12:49 +0300 Subject: [PATCH] mnt: Put root fd to fdstore mntns_get_root_fd() may be called by a task from !root_user_ns, and it fails if so. Put root fd to fdstore to allow use it every task. v3: New Signed-off-by: Kirill Tkhai Signed-off-by: Andrei Vagin --- criu/include/namespaces.h | 2 +- criu/mount.c | 19 +++++++++++++------ criu/sk-unix.c | 13 +++++++++++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h index 820b16d1f..551d18aa3 100644 --- a/criu/include/namespaces.h +++ b/criu/include/namespaces.h @@ -121,7 +121,7 @@ struct ns_id { struct mount_info *mntinfo_list; struct mount_info *mntinfo_tree; int ns_fd; - int root_fd; + int root_fd_id; } mnt; struct { diff --git a/criu/mount.c b/criu/mount.c index 8863a30f1..6377da241 100644 --- a/criu/mount.c +++ b/criu/mount.c @@ -26,6 +26,7 @@ #include "path.h" #include "files-reg.h" #include "external.h" +#include "fdstore.h" #include "images/mnt.pb-c.h" @@ -2788,7 +2789,6 @@ void fini_restore_mntns(void) if (nsid->nd != &mnt_ns_desc) continue; close_safe(&nsid->mnt.ns_fd); - close_safe(&nsid->mnt.root_fd); nsid->ns_populated = true; } } @@ -2982,7 +2982,7 @@ void cleanup_mnt_ns(void) int prepare_mnt_ns(void) { - int ret = -1, rst = -1; + int ret = -1, rst = -1, fd; struct ns_id ns = { .type = NS_CRIU, .ns_pid = PROC_SELF, .nd = &mnt_ns_desc }; struct ns_id *nsid; @@ -3069,10 +3069,17 @@ int prepare_mnt_ns(void) if (cr_pivot_root(path)) goto err; - /* root_fd is used to restore file mappings */ - nsid->mnt.root_fd = open_proc(PROC_SELF, "root"); - if (nsid->mnt.root_fd < 0) + /* root fd is used to restore file mappings */ + fd = open_proc(PROC_SELF, "root"); + if (fd < 0) goto err; + nsid->mnt.root_fd_id = fdstore_add(fd); + if (nsid->mnt.root_fd_id < 0) { + pr_err("Can't add root fd\n"); + close(fd); + goto err; + } + close(fd); /* And return back to regain the access to the roots yard */ if (setns(rst, CLONE_NEWNS)) { @@ -3187,7 +3194,7 @@ int mntns_get_root_fd(struct ns_id *mntns) if (!mntns->ns_populated) { int fd; - fd = open_proc(vpid(root_item), "fd/%d", mntns->mnt.root_fd); + fd = fdstore_get(mntns->mnt.root_fd_id); if (fd < 0) return -1; diff --git a/criu/sk-unix.c b/criu/sk-unix.c index 928a68477..87f292965 100644 --- a/criu/sk-unix.c +++ b/criu/sk-unix.c @@ -28,6 +28,7 @@ #include "pstree.h" #include "external.h" #include "crtools.h" +#include "fdstore.h" #include "protobuf.h" #include "images/sk-unix.pb-c.h" @@ -1036,6 +1037,7 @@ static void revert_unix_sk_cwd(int *prev_cwd_fd, int *root_fd) static int prep_unix_sk_cwd(struct unix_sk_info *ui, int *prev_cwd_fd, int *prev_root_fd) { static struct ns_id *root = NULL; + int fd; *prev_cwd_fd = open(".", O_RDONLY); if (*prev_cwd_fd < 0) { @@ -1052,10 +1054,17 @@ static int prep_unix_sk_cwd(struct unix_sk_info *ui, int *prev_cwd_fd, int *prev goto err; } - if (fchdir(root->mnt.root_fd)) { - pr_perror("Unable to change current working dir"); + fd = fdstore_get(root->mnt.root_fd_id); + if (fd < 0) { + pr_err("Can't get root fd\n"); goto err; } + if (fchdir(fd)) { + pr_perror("Unable to change current working dir"); + close(fd); + goto err; + } + close(fd); if (chroot(".")) { pr_perror("Unable to change root directory"); goto err;