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/go.mod b/go.mod index bd0de40cc..a933248e3 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,7 @@ require ( github.com/moby/sys/sequential v0.6.0 github.com/moby/sys/signal v0.7.1 github.com/moby/sys/symlink v0.3.0 - github.com/moby/sys/user v0.1.0 + github.com/moby/sys/user v0.2.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/opencontainers/runtime-spec v1.2.0 diff --git a/go.sum b/go.sum index aaf668145..4e3a03eef 100644 --- a/go.sum +++ b/go.sum @@ -219,8 +219,8 @@ github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0 github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8= github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU= github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0= -github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= -github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= +github.com/moby/sys/user v0.2.0 h1:OnpapJsRp25vkhw8TFG6OLJODNh/3rEwRWtJ3kakwRM= +github.com/moby/sys/user v0.2.0/go.mod h1:RYstrcWOJpVh+6qzUqp2bU3eaRpdiQeKGlKitaH0PM8= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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_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/pkg/userns/userns_unsupported.go b/pkg/userns/userns_unsupported.go deleted file mode 100644 index c67f773d0..000000000 --- a/pkg/userns/userns_unsupported.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build !linux - -/* - 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 - -// RunningInUserNS is a stub for non-Linux systems -// Always returns false -func RunningInUserNS() bool { - return false -} 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/user.go b/vendor/github.com/moby/sys/user/user.go index 984466d1a..198c49367 100644 --- a/vendor/github.com/moby/sys/user/user.go +++ b/vendor/github.com/moby/sys/user/user.go @@ -197,7 +197,6 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { for { var line []byte line, isPrefix, err = rd.ReadLine() - if err != nil { // We should return no error if EOF is reached // without a match. 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 dbd6a53ee..496bec8b9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -364,9 +364,10 @@ github.com/moby/sys/signal # github.com/moby/sys/symlink v0.3.0 ## explicit; go 1.17 github.com/moby/sys/symlink -# github.com/moby/sys/user v0.1.0 -## explicit; go 1.17 +# 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