diff options
-rw-r--r-- | pkg/rootless/rootless_linux.c | 9 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 39 |
2 files changed, 44 insertions, 4 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 9eb16c1a5..1d28ff68d 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -99,7 +99,7 @@ get_cmd_line_args (pid_t pid) } int -reexec_userns_join (int userns) +reexec_userns_join (int userns, int mountns) { pid_t ppid = getpid (); char uid[16]; @@ -131,6 +131,13 @@ reexec_userns_join (int userns) } close (userns); + if (mountns >= 0 && setns (mountns, 0) < 0) + { + fprintf (stderr, "cannot setns: %s\n", strerror (errno)); + _exit (EXIT_FAILURE); + } + close (userns); + if (syscall_setresgid (0, 0, 0) < 0) { fprintf (stderr, "cannot setresgid: %s\n", strerror (errno)); diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 07002da3f..9a192c0fa 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -25,7 +25,7 @@ import ( /* extern int reexec_in_user_namespace(int ready); extern int reexec_in_user_namespace_wait(int pid); -extern int reexec_userns_join(int userns); +extern int reexec_userns_join(int userns, int mountns); */ import "C" @@ -112,7 +112,40 @@ func JoinNS(pid uint) (bool, int, error) { } defer userNS.Close() - pidC := C.reexec_userns_join(C.int(userNS.Fd())) + pidC := C.reexec_userns_join(C.int(userNS.Fd()), -1) + if int(pidC) < 0 { + return false, -1, errors.Errorf("cannot re-exec process") + } + + ret := C.reexec_in_user_namespace_wait(pidC) + if ret < 0 { + return false, -1, errors.New("error waiting for the re-exec process") + } + + return true, int(ret), nil +} + +// JoinDirectUserAndMountNS re-exec podman in a new userNS and join the user and mount +// namespace of the specified PID without looking up its parent. Useful to join directly +// the conmon process. +func JoinDirectUserAndMountNS(pid uint) (bool, int, error) { + if os.Geteuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" { + return false, -1, nil + } + + userNS, err := os.Open(fmt.Sprintf("/proc/%d/ns/user", pid)) + if err != nil { + return false, -1, err + } + defer userNS.Close() + + mountNS, err := os.Open(fmt.Sprintf("/proc/%d/ns/mnt", pid)) + if err != nil { + return false, -1, err + } + defer userNS.Close() + + pidC := C.reexec_userns_join(C.int(userNS.Fd()), C.int(mountNS.Fd())) if int(pidC) < 0 { return false, -1, errors.Errorf("cannot re-exec process") } @@ -138,7 +171,7 @@ func JoinNSPath(path string) (bool, int, error) { } defer userNS.Close() - pidC := C.reexec_userns_join(C.int(userNS.Fd())) + pidC := C.reexec_userns_join(C.int(userNS.Fd()), -1) if int(pidC) < 0 { return false, -1, errors.Errorf("cannot re-exec process") } |