[CRIU] [PATCH v4 24/31] utils: Introduce open_fd_of_real_pid()
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Feb 22 03:34:04 PST 2017
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 at virtuozzo.com>
---
criu/include/util.h | 2 ++
criu/namespaces.c | 5 -----
criu/util.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/criu/include/util.h b/criu/include/util.h
index d9f50f6e0..c1d38c939 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -307,4 +307,6 @@ extern int epoll_del_rfd(int epfd, struct epoll_rfd *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 371cb32de..0a67903d6 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -1452,11 +1452,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);
- if (fd < 0 && flags & UNS_FDOUT) {
- pr_err("uns: bad flags/fd %p %d %x\n", call, fd, flags);
- BUG();
- }
-
/*
* 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 93a1f7257..9fd8ba285 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1331,3 +1331,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;
+}
More information about the CRIU
mailing list