From 8437c567d89bae1154c4ff926bf96bac39b8f30f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 16 Jul 2024 21:50:24 +0200 Subject: [PATCH] pkg/userns: deprecate and migrate to github.com/moby/sys/user/userns The userns package in libcontainer was integrated into the moby/sys/user module at commit [3778ae603c706494fd1e2c2faf83b406e38d687d][1]. This patch deprecates the containerd fork of that package, and adds it as an alias for the moby/sys/user/userns package. [1]: https://github.com/opencontainers/runc/commit/3778ae603c706494fd1e2c2faf83b406e38d687d Signed-off-by: Sebastiaan van Stijn --- cmd/containerd-shim-runc-v2/task/service.go | 3 +- core/diff/apply/apply_linux.go | 6 +- core/mount/mount_linux.go | 2 +- .../server/podsandbox/sandbox_run_linux.go | 2 +- .../podsandbox/sandbox_run_linux_test.go | 2 +- internal/cri/server/service_linux.go | 2 +- pkg/archive/tar.go | 3 +- pkg/archive/tar_unix.go | 5 +- pkg/oci/utils_unix.go | 2 +- pkg/oci/utils_unix_test.go | 3 +- pkg/sys/oom_linux.go | 2 +- pkg/sys/oom_linux_test.go | 2 +- ...ns_unsupported.go => userns_deprecated.go} | 14 +++-- pkg/userns/userns_linux.go | 62 ------------------- .../snapshots/overlay/overlayutils/check.go | 2 +- .../github.com/moby/sys/user/userns/userns.go | 16 +++++ .../moby/sys/user/userns/userns_linux.go | 53 ++++++++++++++++ .../sys/user/userns/userns_linux_fuzzer.go | 8 +++ .../sys/user/userns/userns_unsupported.go | 6 ++ vendor/modules.txt | 1 + 20 files changed, 112 insertions(+), 84 deletions(-) rename pkg/userns/{userns_unsupported.go => userns_deprecated.go} (66%) delete mode 100644 pkg/userns/userns_linux.go create mode 100644 vendor/github.com/moby/sys/user/userns/userns.go create mode 100644 vendor/github.com/moby/sys/user/userns/userns_linux.go create mode 100644 vendor/github.com/moby/sys/user/userns/userns_linux_fuzzer.go create mode 100644 vendor/github.com/moby/sys/user/userns/userns_unsupported.go diff --git a/cmd/containerd-shim-runc-v2/task/service.go b/cmd/containerd-shim-runc-v2/task/service.go index d78dbb2e6..3df296623 100644 --- a/cmd/containerd-shim-runc-v2/task/service.go +++ b/cmd/containerd-shim-runc-v2/task/service.go @@ -24,6 +24,8 @@ import ( "os" "sync" + "github.com/moby/sys/user/userns" + "github.com/containerd/cgroups/v3" "github.com/containerd/cgroups/v3/cgroup1" cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2" @@ -44,7 +46,6 @@ import ( "github.com/containerd/containerd/v2/pkg/shutdown" "github.com/containerd/containerd/v2/pkg/stdio" "github.com/containerd/containerd/v2/pkg/sys/reaper" - "github.com/containerd/containerd/v2/pkg/userns" "github.com/containerd/errdefs" runcC "github.com/containerd/go-runc" "github.com/containerd/log" diff --git a/core/diff/apply/apply_linux.go b/core/diff/apply/apply_linux.go index e4f4fc44a..7f0882e48 100644 --- a/core/diff/apply/apply_linux.go +++ b/core/diff/apply/apply_linux.go @@ -23,12 +23,12 @@ import ( "os" "strings" + "github.com/moby/sys/user/userns" + "golang.org/x/sys/unix" + "github.com/containerd/containerd/v2/core/mount" "github.com/containerd/containerd/v2/pkg/archive" - "github.com/containerd/containerd/v2/pkg/userns" "github.com/containerd/errdefs" - - "golang.org/x/sys/unix" ) func apply(ctx context.Context, mounts []mount.Mount, r io.Reader, sync bool) (retErr error) { diff --git a/core/mount/mount_linux.go b/core/mount/mount_linux.go index a968acec2..90890d345 100644 --- a/core/mount/mount_linux.go +++ b/core/mount/mount_linux.go @@ -28,8 +28,8 @@ import ( "strings" "time" - "github.com/containerd/containerd/v2/pkg/userns" "github.com/containerd/log" + "github.com/moby/sys/user/userns" "golang.org/x/sys/unix" ) diff --git a/internal/cri/server/podsandbox/sandbox_run_linux.go b/internal/cri/server/podsandbox/sandbox_run_linux.go index e7fd1c941..0fae34d29 100644 --- a/internal/cri/server/podsandbox/sandbox_run_linux.go +++ b/internal/cri/server/podsandbox/sandbox_run_linux.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/containerd/containerd/v2/pkg/oci" + "github.com/moby/sys/user/userns" imagespec "github.com/opencontainers/image-spec/specs-go/v1" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux" @@ -32,7 +33,6 @@ import ( "github.com/containerd/containerd/v2/core/snapshots" "github.com/containerd/containerd/v2/internal/cri/annotations" customopts "github.com/containerd/containerd/v2/internal/cri/opts" - "github.com/containerd/containerd/v2/pkg/userns" ) func (c *Controller) sandboxContainerSpec(id string, config *runtime.PodSandboxConfig, diff --git a/internal/cri/server/podsandbox/sandbox_run_linux_test.go b/internal/cri/server/podsandbox/sandbox_run_linux_test.go index c855e676e..588310843 100644 --- a/internal/cri/server/podsandbox/sandbox_run_linux_test.go +++ b/internal/cri/server/podsandbox/sandbox_run_linux_test.go @@ -22,6 +22,7 @@ import ( "strconv" "testing" + "github.com/moby/sys/user/userns" imagespec "github.com/opencontainers/image-spec/specs-go/v1" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux" @@ -33,7 +34,6 @@ import ( "github.com/containerd/containerd/v2/internal/cri/annotations" "github.com/containerd/containerd/v2/internal/cri/opts" ostesting "github.com/containerd/containerd/v2/pkg/os/testing" - "github.com/containerd/containerd/v2/pkg/userns" ) func getRunPodSandboxTestData() (*runtime.PodSandboxConfig, *imagespec.ImageConfig, func(*testing.T, string, *runtimespec.Spec)) { diff --git a/internal/cri/server/service_linux.go b/internal/cri/server/service_linux.go index 55994d52e..96a08a332 100644 --- a/internal/cri/server/service_linux.go +++ b/internal/cri/server/service_linux.go @@ -19,12 +19,12 @@ package server import ( "fmt" + "github.com/moby/sys/user/userns" "github.com/opencontainers/selinux/go-selinux" "tags.cncf.io/container-device-interface/pkg/cdi" "github.com/containerd/containerd/v2/pkg/cap" "github.com/containerd/containerd/v2/pkg/kernelversion" - "github.com/containerd/containerd/v2/pkg/userns" "github.com/containerd/go-cni" "github.com/containerd/log" ) diff --git a/pkg/archive/tar.go b/pkg/archive/tar.go index 44d8a42a2..0e48c6d0f 100644 --- a/pkg/archive/tar.go +++ b/pkg/archive/tar.go @@ -29,9 +29,10 @@ import ( "syscall" "time" + "github.com/moby/sys/user/userns" + "github.com/containerd/containerd/v2/pkg/archive/tarheader" "github.com/containerd/containerd/v2/pkg/epoch" - "github.com/containerd/containerd/v2/pkg/userns" "github.com/containerd/continuity/fs" "github.com/containerd/log" ) diff --git a/pkg/archive/tar_unix.go b/pkg/archive/tar_unix.go index fa74ef468..866a36824 100644 --- a/pkg/archive/tar_unix.go +++ b/pkg/archive/tar_unix.go @@ -27,10 +27,11 @@ import ( "strings" "syscall" - "github.com/containerd/containerd/v2/pkg/userns" + "github.com/moby/sys/user/userns" + "golang.org/x/sys/unix" + "github.com/containerd/continuity/fs" "github.com/containerd/continuity/sysx" - "golang.org/x/sys/unix" ) func chmodTarEntry(perm os.FileMode) os.FileMode { diff --git a/pkg/oci/utils_unix.go b/pkg/oci/utils_unix.go index 7606ec8e3..f954df797 100644 --- a/pkg/oci/utils_unix.go +++ b/pkg/oci/utils_unix.go @@ -24,7 +24,7 @@ import ( "os" "path/filepath" - "github.com/containerd/containerd/v2/pkg/userns" + "github.com/moby/sys/user/userns" specs "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" ) diff --git a/pkg/oci/utils_unix_test.go b/pkg/oci/utils_unix_test.go index bf751216f..da4838b39 100644 --- a/pkg/oci/utils_unix_test.go +++ b/pkg/oci/utils_unix_test.go @@ -25,9 +25,8 @@ import ( "runtime" "testing" + "github.com/moby/sys/user/userns" "github.com/stretchr/testify/assert" - - "github.com/containerd/containerd/v2/pkg/userns" ) func cleanupTest() { diff --git a/pkg/sys/oom_linux.go b/pkg/sys/oom_linux.go index f439a70c1..5894544d4 100644 --- a/pkg/sys/oom_linux.go +++ b/pkg/sys/oom_linux.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - "github.com/containerd/containerd/v2/pkg/userns" + "github.com/moby/sys/user/userns" "golang.org/x/sys/unix" ) diff --git a/pkg/sys/oom_linux_test.go b/pkg/sys/oom_linux_test.go index 0a55e8cec..da9cf912a 100644 --- a/pkg/sys/oom_linux_test.go +++ b/pkg/sys/oom_linux_test.go @@ -24,7 +24,7 @@ import ( "testing" "time" - "github.com/containerd/containerd/v2/pkg/userns" + "github.com/moby/sys/user/userns" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/pkg/userns/userns_unsupported.go b/pkg/userns/userns_deprecated.go similarity index 66% rename from pkg/userns/userns_unsupported.go rename to pkg/userns/userns_deprecated.go index c67f773d0..e1edbc44b 100644 --- a/pkg/userns/userns_unsupported.go +++ b/pkg/userns/userns_deprecated.go @@ -1,5 +1,3 @@ -//go:build !linux - /* Copyright The containerd Authors. @@ -16,10 +14,16 @@ limitations under the License. */ +// Deprecated: use github.com/moby/sys/user/userns package userns -// RunningInUserNS is a stub for non-Linux systems -// Always returns false +import "github.com/moby/sys/user/userns" + +// RunningInUserNS detects whether we are currently running in a Linux +// user namespace and memoizes the result. It returns false on non-Linux +// platforms. +// +// Deprecated: use [userns.RunningInUserNS]. func RunningInUserNS() bool { - return false + return userns.RunningInUserNS() } diff --git a/pkg/userns/userns_linux.go b/pkg/userns/userns_linux.go deleted file mode 100644 index 6656465ef..000000000 --- a/pkg/userns/userns_linux.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package userns - -import ( - "bufio" - "fmt" - "os" - "sync" -) - -var ( - inUserNS bool - nsOnce sync.Once -) - -// RunningInUserNS detects whether we are currently running in a user namespace. -// Originally copied from github.com/lxc/lxd/shared/util.go -func RunningInUserNS() bool { - nsOnce.Do(func() { - file, err := os.Open("/proc/self/uid_map") - if err != nil { - // This kernel-provided file only exists if user namespaces are supported - return - } - defer file.Close() - - buf := bufio.NewReader(file) - l, _, err := buf.ReadLine() - if err != nil { - return - } - - line := string(l) - var a, b, c int64 - fmt.Sscanf(line, "%d %d %d", &a, &b, &c) - - /* - * We assume we are in the initial user namespace if we have a full - * range - 4294967295 uids starting at uid 0. - */ - if a == 0 && b == 0 && c == 4294967295 { - return - } - inUserNS = true - }) - return inUserNS -} diff --git a/plugins/snapshots/overlay/overlayutils/check.go b/plugins/snapshots/overlay/overlayutils/check.go index 5aedf6cb3..485f53442 100644 --- a/plugins/snapshots/overlay/overlayutils/check.go +++ b/plugins/snapshots/overlay/overlayutils/check.go @@ -24,11 +24,11 @@ import ( "path/filepath" "syscall" + "github.com/moby/sys/user/userns" "golang.org/x/sys/unix" "github.com/containerd/containerd/v2/core/mount" kernel "github.com/containerd/containerd/v2/pkg/kernelversion" - "github.com/containerd/containerd/v2/pkg/userns" "github.com/containerd/continuity/fs" "github.com/containerd/log" ) diff --git a/vendor/github.com/moby/sys/user/userns/userns.go b/vendor/github.com/moby/sys/user/userns/userns.go new file mode 100644 index 000000000..56b24c44a --- /dev/null +++ b/vendor/github.com/moby/sys/user/userns/userns.go @@ -0,0 +1,16 @@ +// Package userns provides utilities to detect whether we are currently running +// in a Linux user namespace. +// +// This code was migrated from [libcontainer/runc], which based its implementation +// on code from [lcx/incus]. +// +// [libcontainer/runc]: https://github.com/opencontainers/runc/blob/3778ae603c706494fd1e2c2faf83b406e38d687d/libcontainer/userns/userns_linux.go#L12-L49 +// [lcx/incus]: https://github.com/lxc/incus/blob/e45085dd42f826b3c8c3228e9733c0b6f998eafe/shared/util.go#L678-L700 +package userns + +// RunningInUserNS detects whether we are currently running in a Linux +// user namespace and memoizes the result. It returns false on non-Linux +// platforms. +func RunningInUserNS() bool { + return inUserNS() +} diff --git a/vendor/github.com/moby/sys/user/userns/userns_linux.go b/vendor/github.com/moby/sys/user/userns/userns_linux.go new file mode 100644 index 000000000..87c1c38ee --- /dev/null +++ b/vendor/github.com/moby/sys/user/userns/userns_linux.go @@ -0,0 +1,53 @@ +package userns + +import ( + "bufio" + "fmt" + "os" + "sync" +) + +var inUserNS = sync.OnceValue(runningInUserNS) + +// runningInUserNS detects whether we are currently running in a user namespace. +// +// This code was migrated from [libcontainer/runc] and based on an implementation +// from [lcx/incus]. +// +// [libcontainer/runc]: https://github.com/opencontainers/runc/blob/3778ae603c706494fd1e2c2faf83b406e38d687d/libcontainer/userns/userns_linux.go#L12-L49 +// [lcx/incus]: https://github.com/lxc/incus/blob/e45085dd42f826b3c8c3228e9733c0b6f998eafe/shared/util.go#L678-L700 +func runningInUserNS() bool { + file, err := os.Open("/proc/self/uid_map") + if err != nil { + // This kernel-provided file only exists if user namespaces are supported. + return false + } + defer file.Close() + + buf := bufio.NewReader(file) + l, _, err := buf.ReadLine() + if err != nil { + return false + } + + return uidMapInUserNS(string(l)) +} + +func uidMapInUserNS(uidMap string) bool { + if uidMap == "" { + // File exist but empty (the initial state when userns is created, + // see user_namespaces(7)). + return true + } + + var a, b, c int64 + if _, err := fmt.Sscanf(uidMap, "%d %d %d", &a, &b, &c); err != nil { + // Assume we are in a regular, non user namespace. + return false + } + + // As per user_namespaces(7), /proc/self/uid_map of + // the initial user namespace shows 0 0 4294967295. + initNS := a == 0 && b == 0 && c == 4294967295 + return !initNS +} diff --git a/vendor/github.com/moby/sys/user/userns/userns_linux_fuzzer.go b/vendor/github.com/moby/sys/user/userns/userns_linux_fuzzer.go new file mode 100644 index 000000000..26ba2e16e --- /dev/null +++ b/vendor/github.com/moby/sys/user/userns/userns_linux_fuzzer.go @@ -0,0 +1,8 @@ +//go:build linux && gofuzz + +package userns + +func FuzzUIDMap(uidmap []byte) int { + _ = uidMapInUserNS(string(uidmap)) + return 1 +} diff --git a/vendor/github.com/moby/sys/user/userns/userns_unsupported.go b/vendor/github.com/moby/sys/user/userns/userns_unsupported.go new file mode 100644 index 000000000..8ed83072c --- /dev/null +++ b/vendor/github.com/moby/sys/user/userns/userns_unsupported.go @@ -0,0 +1,6 @@ +//go:build !linux + +package userns + +// inUserNS is a stub for non-Linux systems. Always returns false. +func inUserNS() bool { return false } diff --git a/vendor/modules.txt b/vendor/modules.txt index 2a553842c..496bec8b9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -367,6 +367,7 @@ github.com/moby/sys/symlink # github.com/moby/sys/user v0.2.0 ## explicit; go 1.21 github.com/moby/sys/user +github.com/moby/sys/user/userns # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd ## explicit github.com/modern-go/concurrent