diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-04-20 10:50:14 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-04-20 17:40:24 +0200 |
commit | 8360fcf82cc17ef55a00870d7e950079a51f2083 (patch) | |
tree | 8d8aa4774d648c8a3101fa3a94d9e7e1828d0be6 | |
parent | e4e42b28dfef0ffd12f2087048dec61f9cb03976 (diff) | |
download | podman-8360fcf82cc17ef55a00870d7e950079a51f2083.tar.gz podman-8360fcf82cc17ef55a00870d7e950079a51f2083.tar.bz2 podman-8360fcf82cc17ef55a00870d7e950079a51f2083.zip |
rootless: skip looking up parent user ns
since we join directly the conmon user namespace, there is no need to
look up its parent user namespace, as we can safely assume it is the
init namespace.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r-- | pkg/rootless/rootless_linux.go | 91 |
1 files changed, 1 insertions, 90 deletions
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 5ddfab7ad..f01ebe5fc 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -124,91 +124,6 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap) return nil } -func readUserNs(path string) (string, error) { - b := make([]byte, 256) - _, err := unix.Readlink(path, b) - if err != nil { - return "", err - } - return string(b), nil -} - -func readUserNsFd(fd uintptr) (string, error) { - return readUserNs(fmt.Sprintf("/proc/self/fd/%d", fd)) -} - -func getParentUserNs(fd uintptr) (uintptr, error) { - const nsGetParent = 0xb702 - ret, _, errno := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(nsGetParent), 0) - if errno != 0 { - return 0, errno - } - return (uintptr)(unsafe.Pointer(ret)), nil -} - -// getUserNSFirstChild returns an open FD for the first direct child user namespace that created the process -// Each container creates a new user namespace where the runtime runs. The current process in the container -// might have created new user namespaces that are child of the initial namespace we created. -// This function finds the initial namespace created for the container that is a child of the current namespace. -// -// current ns -// / \ -// TARGET -> a [other containers] -// / -// b -// / -// NS READ USING THE PID -> c -func getUserNSFirstChild(fd uintptr) (*os.File, error) { - currentNS, err := readUserNs("/proc/self/ns/user") - if err != nil { - return nil, err - } - - ns, err := readUserNsFd(fd) - if err != nil { - return nil, errors.Wrapf(err, "cannot read user namespace") - } - if ns == currentNS { - return nil, errors.New("process running in the same user namespace") - } - - for { - nextFd, err := getParentUserNs(fd) - if err != nil { - if err == unix.ENOTTY { - return os.NewFile(fd, "userns child"), nil - } - return nil, errors.Wrapf(err, "cannot get parent user namespace") - } - - ns, err = readUserNsFd(nextFd) - if err != nil { - return nil, errors.Wrapf(err, "cannot read user namespace") - } - - if ns == currentNS { - if err := unix.Close(int(nextFd)); err != nil { - return nil, err - } - - // Drop O_CLOEXEC for the fd. - _, _, errno := unix.Syscall(unix.SYS_FCNTL, fd, unix.F_SETFD, 0) - if errno != 0 { - if err := unix.Close(int(fd)); err != nil { - logrus.Errorf("failed to close file descriptor %d", fd) - } - return nil, errno - } - - return os.NewFile(fd, "userns child"), nil - } - if err := unix.Close(int(fd)); err != nil { - return nil, err - } - fd = nextFd - } -} - // joinUserAndMountNS 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. @@ -240,11 +155,7 @@ func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) { } }() - fd, err := getUserNSFirstChild(userNS.Fd()) - if err != nil { - return false, -1, err - } - pidC := C.reexec_userns_join(C.int(fd.Fd()), C.int(mountNS.Fd()), cPausePid) + pidC := C.reexec_userns_join(C.int(userNS.Fd()), C.int(mountNS.Fd()), cPausePid) if int(pidC) < 0 { return false, -1, errors.Errorf("cannot re-exec process") } |