Skip to content

Commit

Permalink
rootless: move join namespace inside child process
Browse files Browse the repository at this point in the history
open the namespace file descriptors inside of the child process.

Closes: containers#5873

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Apr 20, 2020
1 parent 8360fcf commit 788fdc6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
45 changes: 31 additions & 14 deletions pkg/rootless/rootless_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,36 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
}
}

static void
join_namespace_or_die (int pid_to_join, const char *ns_file)
{
char ns_path[PATH_MAX];
int ret;
int fd;

ret = snprintf (ns_path, PATH_MAX, "/proc/%d/ns/%s", pid_to_join, ns_file);
if (ret == PATH_MAX)
{
fprintf (stderr, "internal error: namespace path too long\n");
_exit (EXIT_FAILURE);
}

fd = open (ns_path, O_CLOEXEC | O_RDONLY);
if (fd < 0)
{
fprintf (stderr, "cannot open: %s\n", ns_path);
_exit (EXIT_FAILURE);
}
if (setns (fd, 0) < 0)
{
fprintf (stderr, "cannot set namespace to %s: %s\n", ns_path, strerror (errno));
_exit (EXIT_FAILURE);
}
close (fd);
}

int
reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
{
char uid[16];
char gid[16];
Expand Down Expand Up @@ -606,19 +634,8 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
_exit (EXIT_FAILURE);
}

if (setns (userns, 0) < 0)
{
fprintf (stderr, "cannot setns: %s\n", strerror (errno));
_exit (EXIT_FAILURE);
}
close (userns);

if (mountns >= 0 && setns (mountns, 0) < 0)
{
fprintf (stderr, "cannot setns: %s\n", strerror (errno));
_exit (EXIT_FAILURE);
}
close (mountns);
join_namespace_or_die (pid_to_join, "user");
join_namespace_or_die (pid_to_join, "mnt");

if (syscall_setresgid (0, 0, 0) < 0)
{
Expand Down
24 changes: 2 additions & 22 deletions pkg/rootless/rootless_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern uid_t rootless_uid();
extern uid_t rootless_gid();
extern int reexec_in_user_namespace(int ready, char *pause_pid_file_path, char *file_to_read, int fd);
extern int reexec_in_user_namespace_wait(int pid, int options);
extern int reexec_userns_join(int userns, int mountns, char *pause_pid_file_path);
extern int reexec_userns_join(int pid, char *pause_pid_file_path);
*/
import "C"

Expand Down Expand Up @@ -135,27 +135,7 @@ func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
cPausePid := C.CString(pausePid)
defer C.free(unsafe.Pointer(cPausePid))

userNS, err := os.Open(fmt.Sprintf("/proc/%d/ns/user", pid))
if err != nil {
return false, -1, err
}
defer func() {
if err := userNS.Close(); err != nil {
logrus.Errorf("unable to close namespace: %q", err)
}
}()

mountNS, err := os.Open(fmt.Sprintf("/proc/%d/ns/mnt", pid))
if err != nil {
return false, -1, err
}
defer func() {
if err := mountNS.Close(); err != nil {
logrus.Errorf("unable to close namespace: %q", err)
}
}()

pidC := C.reexec_userns_join(C.int(userNS.Fd()), C.int(mountNS.Fd()), cPausePid)
pidC := C.reexec_userns_join(C.int(pid), cPausePid)
if int(pidC) < 0 {
return false, -1, errors.Errorf("cannot re-exec process")
}
Expand Down

0 comments on commit 788fdc6

Please sign in to comment.