From 90719d38f7194726aae9ff5469f23c8c0b00d6fd Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 20 Dec 2022 13:11:59 +0100 Subject: [PATCH 1/2] rootless: inhibit copy mapping for euid != 0 when running with euid != 0, inhibit the copy of the current mappings, even if the kernel allows that. This seems to be the expectation when running in a Kubernetes cluster with a non-root user. Signed-off-by: Giuseppe Scrivano --- pkg/rootless/rootless_linux.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 67e478e739..d9bc8da52d 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -223,6 +223,11 @@ func GetConfiguredMappings(quiet bool) ([]idtools.IDMap, []idtools.IDMap, error) } func copyMappings(from, to string) error { + // when running as non-root always go through the newuidmap/newgidmap + // configuration since this is the expectation when running on Kubernetes + if os.Geteuid() != 0 { + return errors.New("copying mappings is allowed only for root") + } content, err := os.ReadFile(from) if err != nil { return err From 1bac16096043d4ef25b586fb82d6cc92c725d0bb Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 20 Dec 2022 13:10:43 +0100 Subject: [PATCH 2/2] rootless: always create userns with euid != 0 always create a user namespace when running with euid != 0 since the user is not owning the current mount namespace. This issue happened on a Kubernetes cluster, where the pod was running privileged but the UID was not 0, as it was configured in the image itself. Signed-off-by: Giuseppe Scrivano --- libpod/runtime.go | 13 +++++++------ pkg/rootless/rootless_linux.go | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libpod/runtime.go b/libpod/runtime.go index 38d404e21e..df5bf0ef49 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -420,13 +420,14 @@ func makeRuntime(runtime *Runtime) (retErr error) { } logrus.Debugf("Set libpod namespace to %q", runtime.config.Engine.Namespace) - hasCapSysAdmin, err := unshare.HasCapSysAdmin() - if err != nil { - return err + needsUserns := os.Geteuid() != 0 + if !needsUserns { + hasCapSysAdmin, err := unshare.HasCapSysAdmin() + if err != nil { + return err + } + needsUserns = !hasCapSysAdmin } - - needsUserns := !hasCapSysAdmin - // Set up containers/storage var store storage.Store if needsUserns { diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index d9bc8da52d..1937a1330d 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -172,7 +172,7 @@ func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) { if err != nil { return false, 0, err } - if hasCapSysAdmin || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" { + if (os.Geteuid() == 0 && hasCapSysAdmin) || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" { return false, 0, nil } @@ -248,7 +248,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo return false, 0, err } - if hasCapSysAdmin || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" { + if (os.Geteuid() == 0 && hasCapSysAdmin) || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" { if os.Getenv("_CONTAINERS_USERNS_CONFIGURED") == "init" { return false, 0, runInUser() }