diff options
author | Andrei Vagin <avagin@virtuozzo.com> | 2017-02-28 10:26:00 +0300 |
---|---|---|
committer | Pavel Emelyanov <xemul@virtuozzo.com> | 2017-03-06 11:44:05 +0300 |
commit | ebb7087aea8e76387155629b63c4f745db8bb325 (patch) | |
tree | 682e0b3f0c468c39caabe6f846b1cf7bda744c8e | |
parent | 1de7fdff4ae79049c6e940fc9fb9530f676330a5 (diff) |
pipe: reopen pipes via usernsd
If a pipe is inherited (external), it may be impossible to reopen it
from a restored user namespace due to lack of permession,
so in this case we have to reopen it via usernsd.
https://github.com/opencontainers/runc/issues/1333
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Acked-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
-rw-r--r-- | criu/pipes.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/criu/pipes.c b/criu/pipes.c index d665a5946..4d15d739e 100644 --- a/criu/pipes.c +++ b/criu/pipes.c @@ -17,6 +17,7 @@ #include "images/pipe.pb-c.h" #include "images/pipe-data.pb-c.h" #include "fcntl.h" +#include "namespaces.h" static LIST_HEAD(pipes); @@ -213,10 +214,10 @@ err: return ret; } -static int reopen_pipe(int fd, int flags) +static int userns_reopen(void *_arg, int fd, pid_t pid) { - int ret; char path[PSFDS]; + int ret, flags = *(int*)_arg; sprintf(path, "/proc/self/fd/%d", fd); ret = open(path, flags); @@ -227,6 +228,26 @@ static int reopen_pipe(int fd, int flags) return ret; } +static int reopen_pipe(int fd, int flags) +{ + int ret; + char path[PSFDS]; + + sprintf(path, "/proc/self/fd/%d", fd); + ret = open(path, flags); + if (ret < 0) { + if (errno == EACCES) { + /* It may be an external pipe from an another userns */ + ret = userns_call(userns_reopen, UNS_FDOUT, + &flags, sizeof(flags), fd); + } else + pr_perror("Unable to reopen the pipe %s", path); + } + close(fd); + + return ret; +} + static int recv_pipe_fd(struct pipe_info *pi, int *new_fd) { int tmp, fd, ret; |