Commit Graph

1939 Commits

Author SHA1 Message Date
Andrew Halaney
59cc4cc49d pkg/sys: Let more environments create user namespace as the initial user
By restoring the effective capabilities of the thread after setresuid()
we can both:

    1. Use the go runtime to setup the uid_map now that we have the
       capabilities to do so in the thread again
    2. Enable this on distro's which have restrictions around
       unprivileged user namespace creation and usage (since the thread
       is now privileged)

Let's do it. See [0] for more details on this topic. Unlike
unix::Setresuid()[1], which mimics the glibc implementation and acts on all
threads in the process, unix::Cap{s,g}et() are thread local[2] only as we
want, so we can use that directly.

[0]: https://github.com/containerd/containerd/pull/12317#discussion_r2686960671
[1]: e2fef50def/src/syscall/syscall_linux.go (L1217)
[2]: 6fb913b30f/unix/zsyscall_linux.go (L524)
Signed-off-by: Andrew Halaney <ahalaney@netflix.com>
2026-01-14 09:04:32 -06:00
Andrew Halaney
42ce92b222 pkg/sys: Create user namespace as the container's initial user namespace user
Right now containerd uses os.StartProcess() to create a dummy ptraced
process via a fork/exec in a new user namespace, with the uid_map/gid_map
setup.

This doesn't work so well with user limits[0] in the kernel, at least if
you expect the container user to have separate isolation from the host's
"normal users". The kernel's ucount mechanism forms a ucount tuple of (ns, kuid_t)
for each user limit. Say containerd runs as uid 0 in the initial user namespace,
and the container runs as uid 100000 from the inital user namespace point of view.

When the container tries to do things like inotify_add_watch(), the
kernel:

    1. First verifies that the ucount(container user namespace, 100000)
       doesn't exceed its "per user per user namespace limits" and
       increments the counter there. This limit is set by
       /proc/sys/user/max_inotify_watches when in the namespace
    2. Then walks up to the ucount who created this namespace,
       ucount(initial user namespace, 0) and increments their counter as
       well ensuring they don't exceed their limit. In our example this
       is the initial user namespace, this limit is set by
       /proc/sys/fs/inotify/max_user_watches as well as
       /proc/sys/user/max_inotify_watches in that case.

This is done so a user can't escape per user limits by creating a user
namespace and running as different users in that user namespace. The
accounting always rolls back up to the user who created the user
namespace to ensure this, checking limits at each layer.

This means if you have a rogue container they can consume all of
the containerd user's inotify limits. In practice this means global root
is in danger of being denied usage of resources due to the container,
while other less important users are still well within their budget!
In the inotify case for example systemd will fail to start many new
services due to this.

Let's instead create the user namespace *as the container's initial user
namespace user*. This means that all the attribution for these user
limits rolls up to this unimportant user, preventing one container from
exhausting global root's resources, and further isolating each container
from each other (since each pod in k8s runs as its own disjoint set of
users in the initial user namespace).

This is a bit annoying to do in golang. The best option seems to be what
we have here:

    1. Lock OS thread
    2. Manually setresuid() (seteuid implementation in golang mimics
       glibc's and sets the euid for all of the threads, which causes
       issues for other threads running at the same time)
    3. Create user namespace
    4. Undo the setresuid()
    5. Update the uid_map/gid_map as root now (can't do this anymore as
       part of (3) since to update the map you must have CAP_SETUID
       which the container user will not have)

With this in place you can verify the user namespace is owned by the
proper uid via ioctl(fd, NS_GET_OWNER_UID). Some distros block
unprivleged user namespace creation, for those we'll just continue to
create it as containerd's user.

[0]: https://docs.kernel.org/admin-guide/sysctl/user.html#documentation-for-proc-sys-user
Signed-off-by: Andrew Halaney <ahalaney@netflix.com>
2026-01-14 09:04:32 -06:00
Samuel Karp
cb15e731a1 Merge pull request #12732 from pauloappbr/fix/12683-go124-symlink-resolution
fix(oci): handle absolute symlinks in rootfs user lookup
2026-01-14 00:28:45 +00:00
Paulo Oliveira
9bbb1309f0 test(oci): use fstest and mock fs for better symlink coverage
Signed-off-by: Paulo Oliveira <paulo.hco47@gmail.com>
2026-01-13 20:00:34 -03:00
Cindia-blue
fb295b9d4f Tracing: add spans in task/metadata and sandbox paths
This PR adds opt-in tracing spans/attributes in CRI image pull and selected sandbox-related paths to improve debugging and correlation (e.g., sandbox.id/pod metadata). If maintainers prefer a smaller diff, I’m happy to split this into a pull-only PR plus follow-ups.
• follow-up after pull-only PR
• focuses on task/metadata/sandbox/cni setup spans

Signed-off-by: Cindy Li <cindyli@pinterest.com>
2026-01-09 00:05:37 +00:00
Paulo Oliveira
85b5418ef5 fix(oci): handle absolute symlinks in rootfs user lookup
Go 1.24 introduced stricter checks for os.DirFS (via os.Root), which causes failures when /etc/passwd or /etc/group are absolute symlinks pointing outside the mount root (common in NixOS).

This patch introduces a helper that detects absolute symlinks and resolves them relative to the rootfs before opening, preventing the 'path escapes from parent' error.

Fixes #12683

Signed-off-by: Paulo Oliveira <paulo.hco47@gmail.com>
2026-01-08 08:44:30 -03:00
Maksym Pavlenko
253fbe756a Cleanup unit tests
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2026-01-06 10:52:49 -08:00
Youfu Zhang
01fd590a77 pkg/oci: add WithUmask for SpecOpts
opencontainers/runtime-spec#941 added umask field and released with v1.0.2.
This commit add the missing helper function for this field.

Signed-off-by: Youfu Zhang <zhangyoufu@gmail.com>
2025-12-24 09:23:07 +08:00
Krisztian Litkey
c49379c38a cri: deprecate the enable_cdi config option.
Deprecate the enable_cdi config option for CRI. Change it to a
pointer so we can differentiate between an unset value and one
that is set explicitly to false. Treat an omitted setting (nil
value) as enabled. Mark it deprecated in RELEASES.md. Add a
deprecation warning for it. Log that warning if we start up
with enable_cdi explicitly set to false.

Signed-off-by: Krisztian Litkey <krisztian.litkey@intel.com>
2025-12-17 10:52:54 +02:00
Sebastiaan van Stijn
0d27fceeed pkg/tracing: HTTPStatusCodeAttributes: remove use of deprecated SemConv const
The "http.status_code" attribute was deprecated in [SemConv v1.21] in favor
of "http.response.status_code", and the `HTTPStatusCodeKey` const was deprecated
in [SemConv v1.22].

The `HTTPStatusCodeAttributes` utility doesn't appear to be used currently, but
let's update it to use both the old and new variants in case someone still uses
it.

[SemConv v1.21]: https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/semconv/v1.21.0/attribute_group.go#L106-L114
[SemConv v1.22]: https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/semconv/v1.22.0/attribute_group.go#L1444-L1452

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-12 17:31:16 +01:00
dependabot[bot]
13b1f43712 build(deps): bump github.com/containerd/cgroups/v3 from 3.1.0 to 3.1.1
Bumps [github.com/containerd/cgroups/v3](https://github.com/containerd/cgroups) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/containerd/cgroups/releases)
- [Commits](https://github.com/containerd/cgroups/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: github.com/containerd/cgroups/v3
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-11-19 17:48:52 +09:00
Samuel Karp
ee1f94e4d1 ctr: allow rlimit-nofile override
Signed-off-by: Samuel Karp <samuelkarp@google.com>
2025-11-17 21:50:12 -08:00
Akihiro Suda
2e0e47c472 Deprecate cgroup v1
For issue 12443

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-10-31 19:34:16 +09:00
Akihiro Suda
04d8ae1d6f Postpone v2.2 deprecation items to v2.3
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-10-28 00:08:57 +09:00
suranmiao
9e9620dd68 chore: fix some function names in comment
Signed-off-by: suranmiao <solsui@outlook.com>
2025-10-17 09:54:21 -07:00
Fu Wei
61ddcd5372 Merge pull request #12063 from dmcgowan/mount-manager
Add mount manager
2025-10-03 14:01:38 +00:00
Derek McGowan
069cbfe8f0 Use mount manager for temp mounts
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-09-29 17:08:37 -07:00
Osama Abdelkader
739821fc5d pkg/display: use platforms.Format for platform display
Replace manual platform formatting with containerd's platforms.Format()
function to ensure consistent platform string formatting across the
codebase. This removes the TODO comment and handles platform variants
properly.

Fixes the TODO in manifest_printer.go line 124.

Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
2025-09-29 18:15:34 +03:00
Enji Cooper
f45716efed Clean up issues cited by usetesting package with golangci
This commit makes all of the recommended changes to use the `testing`
package helper functions instead of doing the equivalent longhand
versions of the same thing.

This change was needed in order to properly detect errors, as the code
would previously skip running `tenv` stating that it had been deprecated
in favor of `usetesting`.

Signed-off-by: Enji Cooper <yaneurabeya@gmail.com>
2025-09-07 14:07:40 -07:00
Sebastiaan van Stijn
c77b708525 pkg/cio: Close(): use errors.Join to return all errors
Preserve all errors encountered, instead of only the last one.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-03 09:55:56 +02:00
Derek McGowan
cc2a52ca8f Update pkg/oci to use FS interface
Switch to use fs.FS interface over directly requiring path string.
Use os.OpenRoot over continuity RootPath.

Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-08-29 12:59:35 -07:00
Mike Brown
9aebe599ec Merge pull request #12217 from klihub/devel/main/update-nri
nri: update NRI to v0.10.0.
2025-08-22 17:37:09 +00:00
Krisztian Litkey
b7a401f1d2 cri: warn about deprecated v0.1.0-style NRI plugins.
Co-authored-by: Chris Henzie <chrishenzie@google.com>
Signed-off-by: Krisztian Litkey <krisztian.litkey@intel.com>
2025-08-21 21:37:56 +03:00
Maksym Pavlenko
a5390cda20 Merge pull request #11966 from zouyee/master
fix: preserve nsPath on mount failure to ensure cleanup
2025-08-20 03:02:28 +00:00
Maksym Pavlenko
c5372ac8b1 Merge pull request #11942 from thaJeztah/oci_test_WithParentCgroupDevices
pkg/oci: add basic test for WithParentCgroupDevices
2025-08-18 20:51:21 +00:00
Wei Fu
6ce7f6d87a pkg/sys: check SupportsPidFD first
Checking this earlier and bailing is preferable to checking this to after we
try to StartProcess.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
2025-08-12 14:53:29 -04:00
Jose Fernandez
45e02e1dc1 sys: fix pidfd leak in UnshareAfterEnterUserns
UnshareAfterEnterUserns() creates a pidfd via os.StartProcess() with
CLONE_PIDFD but fails to close the file descriptor in any code path,
resulting in a file descriptor leak for every container that uses user
namespace isolation.

The leak occurs because:
- The pidfd is created when PidFD field is set in SysProcAttr
- The original defer block only calls PidfdSendSignal() and
  pidfdWaitid()
- No code path calls unix.Close(pidfd) to release the file descriptor

This causes one pidfd leak per container launch when user namespace
isolation is enabled (e.g., Kubernetes pods with hostUsers: false). In
production environments with high container churn, this can exhaust the
system's file descriptor limit.

Fix the leak by adding a defer statement immediately after process
creation that ensures unix.Close(pidfd) is always called, regardless of
which code path is taken. This guarantees cleanup even if the function
returns early due to errors or lack of pidfd support.

This follows the same cleanup pattern already established in
core/mount/mount_idmapped_utils_linux.go:getUsernsFD() which properly
closes its pidfd.

Closes: #12166
Signed-off-by: Jose Fernandez <josef@netflix.com>
2025-08-06 20:26:48 -06:00
Fu Wei
87742bd35f Merge pull request #11857 from djdongjin/remove-go-version-specific-code
chore: remove go version specific code
2025-07-06 19:02:31 +00:00
yashsingh74
03a44a2d7c fix: Used nolint to ignore the static checks
Signed-off-by: yashsingh74 <yashsingh1774@gmail.com>
2025-06-18 14:16:41 +05:30
yashsingh74
403f86ecc2 fix: QF1012: Use of fmt.Fprintln(...)
Signed-off-by: yashsingh74 <yashsingh1774@gmail.com>
2025-06-18 14:16:41 +05:30
yashsingh74
d93d18c857 fix: QF1001: could apply De Morgan's law (staticcheck)
Signed-off-by: yashsingh74 <yashsingh1774@gmail.com>
2025-06-18 14:16:41 +05:30
Jin Dong
734d52c39c chore: remove specific go version code
Now that we have 1.24.x as go min version, I think
we can remove this go code specific to a lower
version.

Signed-off-by: Jin Dong <djdongjin95@gmail.com>
2025-06-12 21:35:09 -04:00
zouyee
04ce9f884d feat: preserve nsPath on mount failure to ensure cleanup
Signed-off-by: zouyee <zouyee1989@gmail.com>
2025-06-12 14:59:10 +08:00
Mike Brown
4bcd549f74 Merge pull request #11946 from thaJeztah/oci_privileged_no_var
pkg/oci: don't use var for WithPrivileged
2025-06-09 02:00:28 +00:00
Akihiro Suda
cd0f2cc23a Merge pull request #11945 from thaJeztah/oci_no_vars_for_funcs
pkg/oci: don't use vars for WithAllKnownCapabilities, WithAllCurrentCapabilities
2025-06-08 06:19:37 +00:00
Maksym Pavlenko
a6c250ed77 Merge pull request #11938 from thaJeztah/oci_linting
pkg/oci: fix minor linting issues
2025-06-06 22:21:33 +00:00
Phil Estes
0bf07cd5c6 Merge pull request #11939 from thaJeztah/oci_rm_go116
pkg/oci: remove compatibility code for go1.16 and older
2025-06-04 15:02:30 +00:00
Sebastiaan van Stijn
8de612020e pkg/oci: don't use var for WithPrivileged
This variable was introduced in 062c3a00ef,
which didn't describe it as intentional to be able to override the option.

Based on the above, I assume the use of a variable was purely convenience,
the there's no intent for packages to be able to override them, so this
patch changes these to be a regular function.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-04 16:35:13 +02:00
Sebastiaan van Stijn
cf667aa7ee pkg/oci: add basic test for WithParentCgroupDevices
It was not used in the code, and had no coverage, so adding some
basic unit-tests.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-04 16:19:00 +02:00
Sebastiaan van Stijn
d72c21450f pkg/oci: don't use vars for WithAllKnownCapabilities, WithAllCurrentCapabilities
These were introduced in c818a6b13d, refactored
in 808b223536 and bdd84abf05,
and moved in a2d1a8a865, but none provided
a motivation for using a variable / alias for these.

Based on the above, I assume the use of a variable was purely convenience,
the there's no intent for packages to be able to override them, so this
patch changes these to be a regular function.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-04 16:10:41 +02:00
Sebastiaan van Stijn
ac3c3ad5da pkg/oci: cleanup some tests
- Use testify for asserting
- Fix various unhandled errors
- Use native t.TempDir() for temporary files

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-04 13:42:09 +02:00
Sebastiaan van Stijn
4de598d94b pkg/oci: remove compatibility code for go1.16 and older
These were added as part of b7f673790f,
to provide backward compatibility with go1.16, which we no longer
supports, so we can remove this.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-04 12:52:40 +02:00
Sebastiaan van Stijn
17c632e785 pkg/oci: fix minor linting issues
- remove redundant aliases for imports
- rename variables that shadowed imports
- use errors.Is instead of straight error comparing

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-04 12:45:57 +02:00
Derek McGowan
aa9c17c692 Add symlink breakout test for overriden path
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-05-20 16:58:12 -07:00
Akihiro Suda
f209a82ca9 Merge pull request #11860 from thaJeztah/oci_no_panic
pkg/oci: prevent panic for some platform-specific options
2025-05-20 16:53:38 +00:00
Sebastiaan van Stijn
b0052d94a6 pkg/oci: prevent panic for some platform-specific options
Some of these options are designed to be a no-op when used on a Spec
that doesn't match the platform for the option. However, if the given
plaform was not present, they would panic.

This patch:

- Adds an early-return for options that are only applied on a
  specific platform.
- Update the GoDoc for these functions to describe they're a
  no-op on other platforms.
- Adds some rudimentary unit-tests to verify their behavior.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-15 00:44:45 +02:00
Samuel Karp
38c9bb93a3 Revert "perf(applyNaive): avoid walking the tree for each file in the same directory"
This reverts commit d8063c30dd.

Signed-off-by: Samuel Karp <samuelkarp@google.com>
2025-05-12 16:36:10 -07:00
Derek McGowan
7360c739fc Fix image inspect skip over missing content
Rather than exiting early with an error, just output that the content
does not exist locally and continue. This is helpful for displaying
multiplatform images when the content for every platform was not pulled.
If a platform that did not exist locally showed up before one that did,
the inspect would error out before even showing the content.

Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-05-05 16:13:39 -07:00
Derek McGowan
ae9b003d24 Merge pull request #10762 from mxpv/dbg
Enable HTTP debug and trace for transfer based puller
2025-04-24 16:22:02 +00:00
Maksym Pavlenko
17b6e1ef85 Allow streaming to client
Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
2025-04-23 18:03:29 -07:00