700 Commits

Author SHA1 Message Date
Kir Kolyshkin 9aeb7905cf tests/int/selinux: fix skip message
It was a mistake to say that SELinux need to be in the enforcing mode
for these tests to run. It only needs to be enabled.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-03-13 08:40:37 -07:00
Kir Kolyshkin 10ca66bff5 runc exec: implement CPU affinity
As per
- https://github.com/opencontainers/runtime-spec/pull/1253
- https://github.com/opencontainers/runtime-spec/pull/1261

CPU affinity can be set in two ways:
1. When creating/starting a container, in config.json's
   Process.ExecCPUAffinity, which is when applied to all execs.
2. When running an exec, in process.json's CPUAffinity, which
   applied to a given exec and overrides the value from (1).

Add some basic tests.

Note that older kernels (RHEL8, Ubuntu 20.04) change CPU affinity of a
process to that of a container's cgroup, as soon as it is moved to that
cgroup, while newer kernels (Ubuntu 24.04, Fedora 41) don't do that.

Because of the above,
 - it's impossible to really test initial CPU affinity without adding
   debug logging to libcontainer/nsenter;
 - for older kernels, there can be a brief moment when exec's affinity
   is different than either initial or final affinity being set;
 - exec's final CPU affinity, if not specified, can be different
   depending on the kernel, therefore we don't test it.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-03-02 19:17:41 -08:00
Kir Kolyshkin a75076b4a4 Switch to opencontainers/cgroups
This removes libcontainer/cgroups packages and starts
using those from github.com/opencontainers/cgroups repo.

Mostly generated by:

  git rm -f libcontainer/cgroups

  find . -type f -name "*.go" -exec sed -i \
    's|github.com/opencontainers/runc/libcontainer/cgroups|github.com/opencontainers/cgroups|g' \
    {} +

  go get github.com/opencontainers/cgroups@v0.0.1
  make vendor
  gofumpt -w .

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-02-28 15:20:33 -08:00
Rodrigo Campos 352c8d40ac Merge pull request #4636 from lifubang/fix-exec-timens
libct: don't send config to nsexec when joining an existing timens
2025-02-26 05:53:29 -03:00
Kir Kolyshkin e0e22d33ea Merge pull request #4643 from cyphar/dmz-rename
libcontainer: rename dmz -> exeseal
2025-02-24 21:42:27 -08:00
Aleksa Sarai 58a599d28a merge #4593 into opencontainers/runc:main
Kir Kolyshkin (1):
  tests/int: add hooks argv[0] test

LGTMs: rata cyphar
2025-02-25 13:54:46 +11:00
Aleksa Sarai 559bd4ebdf libcontainer: rename dmz -> exeseal
The "dmz" name was originally used because the libcontainer/dmz package
housed the runc-dmz binary, but since we removed it in commit
871057d863 ("drop runc-dmz solution according to overlay solution")
the name is an anachronism and we should just give it a more
self-explanatory name.

So, call it libcontainer/exeseal because the purpose of the package is
to provide tools to seal /proc/self/exe against attackers.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-02-25 13:46:05 +11:00
lfbzhm 74619689ae test: exec into a container with private time ns
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-02-22 16:42:01 +00:00
lfbzhm c8737446d2 Merge pull request #4584 from kolyshkin/test-int-nits
Misc nits to tests/integration
2025-02-14 19:22:02 +08:00
Kir Kolyshkin 99f9ed94dc runc exec: fix setting process.Scheduler
Commit 770728e1 added Scheduler field into both Config and Process,
but forgot to add a mechanism to actually use Process.Scheduler.
As a result, runc exec does not set Process.Scheduler ever.

Fix it, and a test case (which fails before the fix).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-02-11 18:01:30 -08:00
Kir Kolyshkin b9114d91e2 runc exec: fix setting process.ioPriority
Commit bfbd0305b added IOPriority field into both Config and Process,
but forgot to add a mechanism to actually use Process.IOPriority.
As a result, runc exec does not set Process.IOPriority ever.

Fix it, and a test case (which fails before the fix).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-02-11 18:01:30 -08:00
Kir Kolyshkin c283ed102c tests/int: add hooks argv[0] test
Looking into old opened runc issues, I noticed #1663 is there without
any resolution, and wrote this simple test checking if we mangle hook's
argv[0] in any way.

Apparently we're good, but the test actually makes sense to have.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-02-06 22:54:29 -08:00
Akihiro Suda dadea505df Merge pull request #4612 from kolyshkin/fix-systemd-reload
libct/cg/sd: set the DeviceAllow property before DevicePolicy
2025-02-07 11:37:10 +09:00
Kir Kolyshkin b55167e04d tests/int/exec --user: check default HOME
Historically, when HOME is not explicitly set in process.Env,
and UID to run as doesn't have a corresponding entry in container's
/etc/passwd, runc sets HOME=/ as a fallback.

Add the corresponding check, for the sake of backward compatibility
preservation.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-02-06 17:49:17 -08:00
Kir Kolyshkin d84388ae10 libct/cg/sd: set the DeviceAllow property before DevicePolicy
Every unit created by runc need daemon reload since systemd v230.
This breaks support for NVIDIA GPUs, see
https://github.com/opencontainers/runc/issues/3708#issuecomment-2216967210

A workaround is to set DeviceAllow before DevicePolicy.

Also:
 - add a test case (which fails before the fix) by @kolyshkin
 - better explain why we need empty DeviceAllow (by @cyphar)

Fixes 4568.

Reported-by: Jian Wen <wenjianhn@gmail.com>
Co-authored-by: Jian Wen <wenjianhn@gmail.com>
Co-authored-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-02-05 12:16:43 -08:00
Kir Kolyshkin c49b891681 tests: add test to check StartContainer hook env
This is to ensure that changes in Process.Env handling won't affect
StartContainer hook.

Reported-by: lfbzhm <lifubang@acmcoder.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-01-09 18:22:53 +08:00
Kir Kolyshkin a50e6872be tests/int: simplify assignments
Assigning a multi-line value to a bash variable should not be so complex.

While at it, slightly reformat create_runtime_hook.

No functional change.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-01-07 13:54:34 -08:00
Kir Kolyshkin a22ea827a8 tests/int/hooks_so: don't hardcode soname
Reuse the appropriate variables instead.

No functional change.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-01-07 13:54:34 -08:00
Adam Korczynski 21c0968bf1 remove broken fuzzer from oss-fuzz build script
Signed-off-by: Adam Korczynski <adam@adalogics.com>
2024-12-18 16:49:44 +00:00
Kir Kolyshkin 5a838ccbe0 tests/cmd/sd-helper: switch from configs to cgroups
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-12-11 19:08:40 -08:00
Kir Kolyshkin 66fe7db3bc Move test helper binaries
Instead of having every test helper binary in its own directory, let's
use /tests/cmd/_bin as a destination directory.

This allows for simpler setup/cleanup.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-12-11 10:46:33 -08:00
lfbzhm 189749aca4 Merge pull request #4492 from cyphar/nsenter-flexible-joining
nsenter: implement a two-stage join for setns
2024-12-05 17:25:04 +08:00
Kir Kolyshkin 66969827c0 Switch to github.com/moby/sys/capability v0.4.0
This removes the last unversioned package in runc's direct dependencies.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-12-02 13:18:10 -08:00
Aleksa Sarai fffc165d79 tests: add test for 'weird' external namespace joining
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-11-14 00:56:55 +11:00
Aleksa Sarai 68bef803eb merge #4482 into opencontainers/runc:main
lifubang (1):
  drop runc-dmz solution according to overlay solution

LGTMs: AkihiroSuda cyphar
2024-10-29 18:14:18 +11:00
Akihiro Suda c8f5d033c2 docs: remove prompt symbols from shell snippets
Remove prompt symbols (`$`, `%`) for ease of copy-pasting

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2024-10-29 01:38:24 +09:00
lifubang 871057d863 drop runc-dmz solution according to overlay solution
Because we have the overlay solution, we can drop runc-dmz binary
solution since it has too many limitations.

Signed-off-by: lifubang <lifubang@acmcoder.com>
2024-10-28 15:18:07 +00:00
lifubang 34a928550f test join other container userns with selinux enabled
Signed-off-by: lifubang <lifubang@acmcoder.com>
2024-10-25 14:01:05 +08:00
lfbzhm 568231cc4e Revert "increase memory.max in cgroups.bats"
This reverts commit 65a1074c75.

We needed [1] because when we removed the bindfd logic in [2] we had not
yet moved the binary cloning logic to Go and thus it was necessary to
increase the memory limit in CI because the clone was happening after
joining the cgroup. However, [3] finally moved that code to Go and thus
the cloning is now done outside of the container's cgroup and thus is no
longer accounted as part of the container's memory usage at any point.

Now we can properly support running a simple container with lower memory
usage as we did before.

[1]: commit 65a1074c75 ("increase memory.max in cgroups.bats")
[2]: commit b999376fb2 ("nsenter: cloned_binary: remove bindfd logic entirely")
[3]: commit 0e9a3358f8 ("nsexec: migrate memfd /proc/self/exe logic to Go code")

Signed-off-by: lfbzhm <lifubang@acmcoder.com>
[cyphar: fixed commit messages]
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-10-21 19:34:41 +11:00
Aleksa Sarai 515f09f7b1 dmz: use overlayfs to write-protect /proc/self/exe if possible
Commit b999376fb2 ("nsenter: cloned_binary: remove bindfd logic
entirely") removed the read-only bind-mount logic from our cloned binary
code because it wasn't really safe because a container with
CAP_SYS_ADMIN could remove the MS_RDONLY bit and get write access to
/proc/self/exe (even with user namespaces this could've been an issue
because it's not clear if the flags are locked).

However, copying a binary does seem to have a minor performance impact.
The only way to have no performance impact would be for the kernel to
block these write attempts, but barring that we could try to reduce the
overhead by coming up with a mount that cannot have it's read-only bits
cleared.

The "simplest" solution is to create a temporary overlayfs using
fsopen(2) which uses the directory where runc exists as a lowerdir,
ensuring that the container cannot access the underlying file -- and we
don't have to do any copies.

While fsopen(2) is not free because mount namespace cloning is usually
expensive (and so it seems like the difference would be marginal), some
basic performance testing seems to indicate there is a ~60% improvement
doing it this way and that it has effectively no overhead even when
compared to just using /proc/self/exe directly:

  % hyperfine --warmup 50 \
  >           "./runc-noclone run -b bundle ctr" \
  >           "./runc-overlayfs run -b bundle ctr" \
  >           "./runc-memfd run -b bundle ctr"

  Benchmark 1: ./runc-noclone run -b bundle ctr
    Time (mean ± σ):      13.7 ms ±   0.9 ms    [User: 6.0 ms, System: 10.9 ms]
    Range (min … max):    11.3 ms …  16.1 ms    184 runs

  Benchmark 2: ./runc-overlayfs run -b bundle ctr
    Time (mean ± σ):      13.9 ms ±   0.9 ms    [User: 6.2 ms, System: 10.8 ms]
    Range (min … max):    11.8 ms …  16.0 ms    180 runs

  Benchmark 3: ./runc-memfd run -b bundle ctr
    Time (mean ± σ):      22.6 ms ±   1.3 ms    [User: 5.7 ms, System: 20.7 ms]
    Range (min … max):    19.9 ms …  26.5 ms    114 runs

  Summary
    ./runc-noclone run -b bundle ctr ran
      1.01 ± 0.09 times faster than ./runc-overlayfs run -b bundle ctr
      1.65 ± 0.15 times faster than ./runc-memfd run -b bundle ctr

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-10-20 21:35:09 +11:00
Aleksa Sarai 8cfbccb6d9 tests: integration: add helper to check if we're in a userns
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-10-20 19:58:49 +11:00
lfbzhm 8bebdbafd8 Merge pull request #4456 from kolyshkin/misc-ci-cleanups
Misc tests/int cleanups
2024-10-18 21:29:53 +08:00
Kir Kolyshkin 54ef07d899 tests/int: skip "update memory vs CheckBeforeUpdate" on EL9
This test case is frequently hanging recently. Might be caused
by a recent kernel update from 5.14.0-427.33.1.el9_4.x86_64 to
5.14.0-427.37.1.el9_4.x86_64.

Could not reproduce locally.

Let's skip it for now.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-17 19:11:01 -07:00
Kir Kolyshkin ff7753636f tests/int: rm centos-7 exclusion
We no longer run tests on CentOS 7, so this is now useless.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-17 18:08:14 -07:00
Kir Kolyshkin 76a821fab7 tests/int: update info about EL9 kernel
The issue quoted is now fixed, so add some information about the fixed
kernel version, and remove links to older discussions about idmapped
mounts security.

We can actually remove all of it for now, but let's keep it. Change
the skip message to say which kernel is required.

Amends commit b460dc39.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-17 18:08:14 -07:00
Kir Kolyshkin 3e3f96034f runc exec --cap: do not add capabilities to ambient
Commit 98fe566c removed setting inheritable capabilities from runc exec
--cap, but neglected to also remove ambient capabilities.

An ambient capability could only be set if the same inheritable
capability is set, so as a result of the above change ambient
capabilities were not set (but due to a bug in gocapability package,
those errors are never reported).

Once we start using a library with the fix [1], that bug will become
apparent. Alas, we do not have any tests for runc exec --cap, so add
one.

Yet, if some inheritable bits are already set from spec, let's set
ambient to avoid a possible regression. Add a test case for that, too.

[1]: https://github.com/kolyshkin/capability/pull/3

Fixes: 98fe566c ("runc: do not set inheritable capabilities")
Co-authored-by: lifubang <lifubang@acmcoder.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-25 21:48:29 -07:00
Kir Kolyshkin 30f8f51eab runc create/run: warn on rootless + shared pidns + no cgroup
Shared pid namespace means `runc kill` (or `runc delete -f`) have to
kill all container processes, not just init. To do so, it needs a cgroup
to read the PIDs from.

If there is no cgroup, processes will be leaked, and so such
configuration is bad and should not be allowed. To keep backward
compatibility, though, let's merely warn about this for now.

Alas, the only way to know if cgroup access is available is by returning
an error from Manager.Apply. Amend fs cgroup managers to do so (systemd
doesn't need it, since v1 can't work with rootless, and cgroup v2 does
not have a special rootless case).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-17 22:49:37 -07:00
Kir Kolyshkin 21c6116557 tests/int: log when teardown starts
This aids in failed test analysis by allowing to distinguish the output
of various commands being run as part of the test case from the output
of teardown command like runc delete.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-17 22:49:37 -07:00
Aleksa Sarai d8844e2939 tests: integration: add setgid mkdirall test
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-09-13 23:34:33 +10:00
Aleksa Sarai 457e1ffa4c tests: add regression test for CVE-2019-19921 / CVE-2023-27561
We reintroduced this once already because it is quite easy to miss this
subtle aspect of proc mounting. The recent migration to
securejoin.MkdirAllInRoot could have also inadvertently reintroduced
this (though it didn't).

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-09-13 17:57:42 +10:00
Akihiro Suda 429e06a518 libct: Signal: honor RootlessCgroups
`signalAllProcesses()` depends on the cgroup and is expected to fail
when runc is running in rootless without an access to the cgroup.

When `RootlessCgroups` is set to `true`, runc just ignores the error
from `signalAllProcesses` and may leak some processes running.
(See the comments in PR 4395)
In the future, runc should walk the process tree to avoid such a leak.

Note that `RootlessCgroups` is a misnomer; it is set to `false` despite
the name when cgroup v2 delegation is configured.
This is expected to be renamed in a separate commit.

Fix issue 4394

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2024-09-11 03:54:52 +09:00
Akihiro Suda f76489f0af mv contrib/cmd tests/cmd (except memfd-bind)
The following commands are moved from `contrib/cmd` to `tests/cmd`:
- fs-idmap
- pidfd-kill
- recvtty
- remap-rootfs
- sd-helper
- seccompagent

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2024-08-16 00:55:48 +09:00
Kir Kolyshkin a7c8d86fc1 tests/int: fix "cpu burst" failure on new kernels
A kernel bug which resulted in cpu.max.burst value read which is 1000
times smaller than it should be has recently been fixed (see [1]).

Adapt the test so it works with either broken or fixed kernel.

[1]: https://lore.kernel.org/all/20240424132438.514720-1-serein.chengyu@huawei.com/

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-08-13 17:54:23 -07:00
Kir Kolyshkin b437ed3063 tests/int: check_{systemd,cgroup}_value: better log
1. Rename current -> got, expected -> want.
2. check_cgroup_value: add file name to output.
3. Improve functions description.

This is mostly to simplify debugging test failures.
Example output before:

	current 500000 !? 500

After:

	cpu.max.burst: got 500000, want 500

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-08-13 17:44:31 -07:00
Akihiro Suda a5e660ca5b seccomp-notify.bats: add fcntl to the important syscall list
For issue 4328

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2024-07-04 02:05:31 +09:00
Kir Kolyshkin 1c505fffdc Revert "Set temporary single CPU affinity..."
There's too much logic here figuring out which CPUs to use. Runc is a
low level tool and is not supposed to be that "smart". What's worse,
this logic is executed on every exec, making it slower. Some of the
logic in (*setnsProcess).start is executed even if no annotation is set,
thus making ALL execs slow.

Also, this should be a property of a process, rather than annotation.

The plan is to rework this.

This reverts commit afc23e3397.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-06-10 06:31:03 +08:00
Kir Kolyshkin 771903608c libct/cg: write unified resources line by line
It has been pointed out that some controllers can not accept multiple
lines of output at once. In particular, io.max can only set one device
at a time.

Practically, the only multi-line resource values we can get come from
unified.* -- let's write those line by line.

Add a test case.

Reported-by: Tao Shen <shentaoskyking@gmail.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-06-09 14:01:45 -07:00
Kir Kolyshkin 3083bd443f tests/cgroups: separate cgroup v2 swap test
There are cgroup v2 systems out there that do not have cgroup swap enabled,
and this test will probably fail in there.

Move it to a separate case, guarded with requires cgroups_swap.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-06-06 18:52:34 +08:00
Kir Kolyshkin dbb011ecd9 tests/int/helpers: fix cgroups_swap check for v2
In case of cgroup v2, there's no memory.swap.max in the top-level
cgroup, so we have to use find.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-06-06 18:52:34 +08:00
Kir Kolyshkin 8626c7173e tests/int: fixup find statements
1. Add "-maxdepth 2" to not dive too deep into cgroup hierarchy.

2. Add "-type f" to look for a regular file.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-06-06 18:52:34 +08:00