[v2,28/36] utils: Introduce open_fd_of_real_pid()

Submitted by Kirill Tkhai on Feb. 3, 2017, 4:15 p.m.

Details

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

Commit Message

Kirill Tkhai Feb. 3, 2017, 4:15 p.m.
As access to /proc/[pid]/fd/[i] of a task from parent's
user_ns is prohibited, introduce a helper, doing that
via usernsd.

Also, remove BUG_ON() in usernsd, as now it may be used
without input fd parameter.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/util.h |    2 ++
 criu/namespaces.c   |    2 --
 criu/util.c         |   30 ++++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/util.h b/criu/include/util.h
index 21ea3d98e..6c52f960e 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -306,4 +306,6 @@  extern int epoll_add_rfd(int epfd, struct epoll_rfd *);
 extern int epoll_run_rfds(int epfd, struct epoll_event *evs, int nr_fds, int tmo);
 extern int epoll_prepare(int nr_events, struct epoll_event **evs);
 
+extern int open_fd_of_real_pid(pid_t pid, int fd, int flags);
+
 #endif /* __CR_UTIL_H__ */
diff --git a/criu/namespaces.c b/criu/namespaces.c
index fd390c938..5a47a4971 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -1442,8 +1442,6 @@  static int usernsd(int sk)
 		unsc_msg_pid_fd(&um, &pid, &fd);
 		pr_debug("uns: daemon calls %p (%d, %d, %x)\n", call, pid, fd, flags);
 
-		BUG_ON(fd < 0 && flags & UNS_FDOUT);
-
 		/*
 		 * Caller has sent us bare address of the routine it
 		 * wants to call. Since the caller is fork()-ed from the
diff --git a/criu/util.c b/criu/util.c
index b171781aa..a26dfe0c8 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1302,3 +1302,33 @@  int epoll_prepare(int nr_fds, struct epoll_event **events)
 	xfree(*events);
 	return -1;
 }
+
+static int fn_open_proc_r(void *path, int fd, pid_t pid)
+{
+	return openat(get_service_fd(CR_PROC_FD_OFF), path, O_RDONLY);
+}
+static int fn_open_proc_w(void *path, int fd, pid_t pid)
+{
+	return openat(get_service_fd(CR_PROC_FD_OFF), path, O_WRONLY);
+}
+static int fn_open_proc_rw(void *path, int fd, pid_t pid)
+{
+	return openat(get_service_fd(CR_PROC_FD_OFF), path, O_RDWR);
+}
+
+int open_fd_of_real_pid(pid_t pid, int fd, int flags)
+{
+	char path[64];
+	int ret;
+
+	ret = sprintf(path, "%d/fd/%d", pid, fd);
+	if (flags == O_RDONLY)
+		ret = userns_call(fn_open_proc_r, UNS_FDOUT, path, ret + 1, -1);
+	else if (flags == O_WRONLY)
+		ret = userns_call(fn_open_proc_w, UNS_FDOUT, path, ret + 1, -1);
+	else if (flags == O_RDWR)
+		ret = userns_call(fn_open_proc_rw, UNS_FDOUT, path, ret + 1, -1);
+	else
+		BUG();
+	return ret;
+}