From 941fd23b04d57160f9b05f98355b95e571cbf143 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 21 May 2018 14:45:27 -0400 Subject: [PATCH] Decide how to chroot based on capabilities, not uid_map contents When deciding whether to pivot_root or chroot in pkg/chrootarchive, check if we have CAP_SYS_CHROOT and CAP_SYS_ADMIN, instead of checking if we have non-default UID mappings, which don't directly affect whether or not we'll be able to do one or the other of those things. Signed-off-by: Nalin Dahyabhai --- pkg/chrootarchive/chroot_linux.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/chrootarchive/chroot_linux.go b/pkg/chrootarchive/chroot_linux.go index e8bd22e36..76c94c6c1 100644 --- a/pkg/chrootarchive/chroot_linux.go +++ b/pkg/chrootarchive/chroot_linux.go @@ -7,7 +7,7 @@ import ( "path/filepath" "github.com/containers/storage/pkg/mount" - rsystem "github.com/opencontainers/runc/libcontainer/system" + "github.com/syndtr/gocapability/capability" "golang.org/x/sys/unix" ) @@ -18,10 +18,16 @@ import ( // Old root is removed after the call to pivot_root so it is no longer available under the new root. // This is similar to how libcontainer sets up a container's rootfs func chroot(path string) (err error) { - // if the engine is running in a user namespace we need to use actual chroot - if rsystem.RunningInUserNS() { + caps, err := capability.NewPid(0) + if err != nil { + return err + } + + // if the process doesn't have CAP_SYS_ADMIN, but does have CAP_SYS_CHROOT, we need to use the actual chroot + if !caps.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN) && caps.Get(capability.EFFECTIVE, capability.CAP_SYS_CHROOT) { return realChroot(path) } + if err := unix.Unshare(unix.CLONE_NEWNS); err != nil { return fmt.Errorf("Error creating mount namespace before pivot: %v", err) }