aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2020-04-20 10:50:14 +0200
committerGiuseppe Scrivano <giuseppe@scrivano.org>2020-04-23 21:28:40 +0200
commitba9a92d839abf2378dac02a02cbf1e33992d197b (patch)
tree8e164376ee0705338c8e58383f4579a1d8c5b24d
parent6f28c92865c4ac262bce790ecda2a07d1127760f (diff)
downloadpodman-ba9a92d839abf2378dac02a02cbf1e33992d197b.tar.gz
podman-ba9a92d839abf2378dac02a02cbf1e33992d197b.tar.bz2
podman-ba9a92d839abf2378dac02a02cbf1e33992d197b.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> (cherry picked from commit 8360fcf82cc17ef55a00870d7e950079a51f2083)
-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")
}