Some rootfs may use symlinks for /etc/passwd and /etc/group. For example,
NixOS uses absolute symlinks to files in /nix/store. os.Root is not used
because it rejects absolute symlinks.
The previous code only handled a symlink on the final path. Add a helper to
resolve symlinks in every path component with fs.ReadLinkFS. Absolute symlinks
are resolved from the rootfs, and the final path is still opened with fs.FS.
When tracing a path through symbolic links, the maximum number of links that
can be followed is [40][1].
[1]: <https://man7.org/linux/man-pages/man7/path_resolution.7.html>
Signed-off-by: Wei Fu <fuweid89@gmail.com>
`populateDefaultUnixSpec` uses `filepath.Join` to generate the default
`CgroupsPath`. On Windows, this produces invalid paths as path elems are
joined with backslash. Switch to `path.Join` instead.
Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
`strconv.NumError` implements `Unwrap` (see https://go.dev/cl/194563),
so there's no need to manually assert the type and unwrap.
Updates 9439355c2b
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
openUserFile now stats the opened file, refuses anything that is not a
regular file, and wraps the returned fs.File so reads are capped at
maxUserFileBytes (10 MiB). All callers of openUserFile read either
etc/passwd or etc/group; both are regular files on real systems, well
under the cap.
The cap and the regular-file check together bound parser memory use
when reading user-database files of unexpected shape or size.
Adds tests for the cap and for the non-regular file rejection. The cap
test covers three boundary points: a small pad (trailing entry parsed),
a pad placing the entry's last byte exactly on the cap (still parsed),
and a pad past the cap (read returns an "exceeds" error).
Assisted-by: Antigravity
Signed-off-by: Chris Henzie <chrishenzie@gmail.com>
Commit f9c80be1b removed varcheck linter, but some nolint:varcheck
annotations are still there, resulting in golangci-lint warning:
> WARN [runner/nolint_filter] Found unknown linters in //nolint directives: varcheck
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The `os.IsNotExist` documentation is clear that it should only be used to
check the error returned from calls within the os package, calls via
`fs.FS` should use `errors.Is`.
Signed-off-by: Derek McGowan <derek@mcg.dev>
Remove `runtime.GOOS == "darwin"` checks from WithUser,
WithAdditionalGIDs, and WithAppendAdditionalGroups. These guards
prevented supplementary group resolution when containerd runs on a
non-Linux host (e.g. macOS or Windows) that creates Linux containers.
The `s.Windows != nil` check for LCOW is retained.
Move user/group tests from spec_opts_linux_test.go to the new
cross-platform spec_opts_user_test.go so they run on all platforms.
Signed-off-by: Rob Murray <rob.murray@docker.com>
newFakeImage used digest.NewDigestFromBytes which hex-encodes the raw
bytes rather than hashing them, producing a digest with an invalid
length. This was previously harmless since the embedded data path in
content.ReadBlob never matched, but now that the digest is validated
before use, the invalid digest causes an error.
Use digest.Canonical.FromBytes which correctly hashes the content.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This is a follow-up to PR #12732.
As noted by @TheColorman, while the previous PR successfully resolved absolute symlinks pointing outside the mount root for /etc/passwd during user lookups, the same logic was missing for group lookups. This caused `openat etc/group: path escapes from parent` errors when /etc/group was also an absolute symlink (e.g., in NixOS environments).
This patch updates GIDFromFS, getSupplementalGroupsFromFS, and WithAppendAdditionalGroups to use the openUserFile helper, ensuring absolute symlinks are correctly re-anchored across all OCI user/group resolution paths. Includes unit test for validation.
Fixes#12683
Signed-off-by: Paulo Oliveira <paulo.hco47@gmail.com>
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>
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>
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>
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>
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>
- Use testify for asserting
- Fix various unhandled errors
- Use native t.TempDir() for temporary files
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
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>
- 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>
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>
The CDI device injection spec opt was mistakenly added to the OCI
package which brought in an unintended dependency on CDI and its
transitive dependencies.
Signed-off-by: Derek McGowan <derek@mcg.dev>
Commit 8437c567d8 migrated the use of the
userns package to the github.com/moby/sys/user module.
After further discussion with maintainers, it was decided to move the
userns package to a separate module, as it has no direct relation with
"user" operations (other than having "user" in its name).
This patch migrates our code to use the new module.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
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 <github@gone.nl>
There's a couple spots where we know exactly how large
the destination buffer should be, so pre-size these to
avoid any reallocs to a higher capacity.
Signed-off-by: Danny Canter <danny@dcantah.dev>
Allow the api to stay at the same v1 go package name and keep using a
1.x version number. This indicates the API is still at 1.x and allows
sharing proto types with containerd 1.6 and 1.7 releases.
Signed-off-by: Derek McGowan <derek@mcg.dev>
This includes migrating from cdi.GetRegistry() to cdi.Configure() and
using top-level cdi Refresh and InjectDevices functions as applicable.
Signed-off-by: Evan Lezar <elezar@nvidia.com>