summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2020-04-20 10:50:14 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2020-04-20 17:40:24 +0200
commit8360fcf82cc17ef55a00870d7e950079a51f2083 (patch)
tree8d8aa4774d648c8a3101fa3a94d9e7e1828d0be6
parente4e42b28dfef0ffd12f2087048dec61f9cb03976 (diff)
downloadpodman-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.go91
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")
}