[v4,04/41] mnt: Put root fd to fdstore

Submitted by Kirill Tkhai on May 4, 2017, 4:05 p.m.

Details

Message ID 149391393153.11711.16616004954107083536.stgit@localhost.localdomain
State New
Series "Nested pid namespaces support"
Headers show

Commit Message

Kirill Tkhai May 4, 2017, 4:05 p.m.
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 <ktkhai@virtuozzo.com>
---
 criu/include/namespaces.h |    2 +-
 criu/mount.c              |   19 +++++++++++++------
 criu/sk-unix.c            |   11 ++++++++++-
 3 files changed, 24 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

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 7ff076782..2ea3d5dce 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"
 
@@ -2768,7 +2769,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;
 	}
 }
@@ -2962,7 +2962,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;
 
@@ -3049,10 +3049,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)) {
@@ -3165,7 +3172,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 a7f09a4b8..e05117907 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"
@@ -884,6 +885,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) {
@@ -900,10 +902,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)) {
+		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;