Skip to content

Commit

Permalink
pipe: reopen pipes via usernsd
Browse files Browse the repository at this point in the history
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.

opencontainers/runc#1333
  • Loading branch information
avagin committed Feb 23, 2017
1 parent 204f44d commit 9986792
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions criu/pipes.c
Expand Up @@ -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);

Expand Down Expand Up @@ -213,15 +214,42 @@ int restore_pipe_data(int img_type, int pfd, u32 id, struct pipe_data_rst **hash
return ret;
}

struct uns_reopen_args {
int flags;
};

static int userns_reopen(void *_arg, int fd, pid_t pid)
{
struct uns_reopen_args *arg = _arg;
char path[PSFDS];
int ret;

sprintf(path, "/proc/self/fd/%d", fd);
ret = open(path, arg->flags);
if (ret < 0)
pr_perror("Unable to reopen the pipe %s", path);
close(fd);

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)
pr_perror("Unable to reopen the pipe %s", path);
if (ret < 0) {
if (errno == EACCES) {
/* It may be an external pipe from an another userns */
struct uns_reopen_args args = {
.flags = flags
};
ret = userns_call(userns_reopen, UNS_FDOUT, &args, sizeof(args), fd);
} else
pr_perror("Unable to reopen the pipe %s", path);
}
close(fd);

return ret;
Expand Down

0 comments on commit 9986792

Please sign in to comment.