Since go 1.14, mod=vendor is used automatically. Since go 1.16 is now
released, and minimally supported go version is 1.15.
As per commit fbeed5228, remove the go 1.13 workaround.
Fix README to require go 1.14.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This adds a checkpoint/restore test to ensure that nested bind mount
mountpoints are correctly re-created.
Signed-off-by: Adrian Reber <areber@redhat.com>
runc was already re-creating mountpoints before calling CRIU to restore
a container. But mountpoints inside a bind mount were not re-created.
During initial container creation runc will mount bind mounts and then
create the necessary mountpoints for further mounts inside those bind
mounts.
If, for example, one of the bind mounts is a tmpfs and empty before
restore, CRIU will fail re-mounting all mounts because the mountpoints
in the bind mounted tmpfs no longer exist.
CRIU expects all mount points to exist as during checkpointing.
This changes runc to mount bind mounts after mountpoint creation to
ensure nested bind mounts have their mountpoints created before CRIU
does the restore.
Signed-off-by: Adrian Reber <areber@redhat.com>
1. Get rid of fixed ROOT, *_BUNDLE, and CONSOLE_SOCKET dirs.
Now they are temporary directories created in setup_bundle.
2. Automate containers cleanup: instead of having to specify all
containers to be removed, list and destroy everything (which is
now possible since every test case has its own unique root).
3. Randomize cgroup paths so two tests running in parallel won't
use the same cgroup.
Now it's theoretically possible to execute tests in parallel.
Practically it's not possible yet because bats uses GNU parallel,
which do not provide a terminal for whatever it executes, and
many runc tests (all those that run containers with terminal:
true) needs a tty. This may possibly be addressed later.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Do not depend on $DEBIAN_BUNDLE, instead use the current directory.
2. Simplify setup() by calling teardown().
3. In teardown(), check that LIBPATH is set.
4. Move global variables into setup.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
It's a little known fact, but BATS_TMPDIR is just /tmp, and it is not
being cleaned by bats after the test.
BATS_RUN_TMPDIR (available since bats 1.2.1) is $BATS_TMPDIR/bats-run-$$
(i.e. it is per bats run and includes PID), and it is cleaned up after
the test (unless --no-tmpdir-cleanup is given).
Use BATS_RUN_TMPDIR for better isolation and cleanup.
[v2: check for BATS_RUN_TMPDIR, effectively requiring bats >= 1.2.1]
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Overloading $HELLO_BUNDLE with a second purpose of having an alternative
runc root is confusing.
Instead, let's create a temp directory in setup() and clean it up in
teardown().
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
... by using retry, to avoid code duplication.
While at it, make it check the number of arguments and error out on
invalid usage.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
It is only used in a couple of places and is easy to replace
with ROOT=xxx teardown_running_container.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
All the tests are run with cd to bundle directory, so
it does not make ense to explicitly specify it.
This relies on the feature of functions like set_cgroups_path
or update_config to use current directory by default.
In those cases where we need to change the directory
(runc create/run -b), save the current one and use it later.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The test verifies if the device file can be queried using
'access(dev_name, F_OK)' when the permissions are set to 'rw'. The call
does not explicitly trigger read or write access but should succeed.
Signed-off-by: Vasiliy Ulyanov <vulyanov@suse.de>
Checking the access mode as bellow
if (R3 & bpfAccess == 0 /* use R1 as a temp var */) goto next
does not handle correctly device file probing with:
access(dev_name, F_OK)
F_OK does not trigger read or write access. Instead the access type in
R3 in that case will be zero and the check will not pass even if "rw" is
allowed for the device file. Comparing the 'masked' access type with the
requested one solves the issue:
if (R3 & bpfAccess != R3 /* use R1 as a temp var */) goto next
Signed-off-by: Vasiliy Ulyanov <vulyanov@suse.de>
As reported by go test -race ./libcontainer/configs:
=== RUN TestCommandHookRunTimeout
==================
WARNING: DATA RACE
Read at 0x00c000202230 by goroutine 23:
os/exec.(*Cmd).Wait()
/usr/lib/golang/src/os/exec/exec.go:502 +0x91
github.com/opencontainers/runc/libcontainer/configs.Command.Run()
/home/kir/go/src/github.com/opencontainers/runc/libcontainer/configs/config.go:390 +0x58c
github.com/opencontainers/runc/libcontainer/configs_test.TestCommandHookRunTimeout()
/home/kir/go/src/github.com/opencontainers/runc/libcontainer/configs/config_test.go:223 +0x3ed
testing.tRunner()
/usr/lib/golang/src/testing/testing.go:1123 +0x202
Previous write at 0x00c000202230 by goroutine 27:
os/exec.(*Cmd).Wait()
/usr/lib/golang/src/os/exec/exec.go:505 +0xb4
github.com/opencontainers/runc/libcontainer/configs.Command.Run.func1()
/home/kir/go/src/github.com/opencontainers/runc/libcontainer/configs/config.go:373 +0x55
Goroutine 23 (running) created at:
testing.(*T).Run()
/usr/lib/golang/src/testing/testing.go:1168 +0x5bb
testing.runTests.func1()
/usr/lib/golang/src/testing/testing.go:1439 +0xa6
testing.tRunner()
/usr/lib/golang/src/testing/testing.go:1123 +0x202
testing.runTests()
/usr/lib/golang/src/testing/testing.go:1437 +0x612
testing.(*M).Run()
/usr/lib/golang/src/testing/testing.go:1345 +0x3b3
main.main()
_testmain.go:69 +0x236
Goroutine 27 (running) created at:
github.com/opencontainers/runc/libcontainer/configs.Command.Run()
/home/kir/go/src/github.com/opencontainers/runc/libcontainer/configs/config.go:372 +0x415
github.com/opencontainers/runc/libcontainer/configs_test.TestCommandHookRunTimeout()
/home/kir/go/src/github.com/opencontainers/runc/libcontainer/configs/config_test.go:223 +0x3ed
testing.tRunner()
/usr/lib/golang/src/testing/testing.go:1123 +0x202
==================
testing.go:1038: race detected during execution of test
--- FAIL: TestCommandHookRunTimeout (0.10s)
Apparently, the issue is we call two Wait()s for the same command
which can race internally.
Fix is easy -- since we already have a waiting goroutine,
wait for it to return instead of calling a second Wait().
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This test fails to compile on i386:
> libcontainer/seccomp/patchbpf/enosys_linux_test.go:180:20: constant 3735928559 overflows int
> libcontainer/seccomp/patchbpf/enosys_linux_test.go:204:19: constant 3735928559 overflows int
> libcontainer/seccomp/patchbpf/enosys_linux_test.go:227:25: constant 3735928559 overflows int
This is because golang.org/x/net/bpf returns an int from their emulated
BPF VM implementation when they should really be returning uint32.
Fix by switching to uint32 in the test code.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
In the past we incorrectly handled eBPF errors in two ways:
1. We would only ignore errors if there was an allow rule in the list
(this doesn't make sense because for security purposes we only care
if a *deny* rule is being ignored). Arguably this is a security flaw
but you would only get an error from bpf(2) in rare cases, and thus
is not a big enough deal to go through security review.
2. If we were in a rootless container we would still return an error
even though bpf(2) is blocked for rootless containers.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
It appears that briefly thawing the cgroup while freezing
greatly increases its chances to freeze successfully.
The test case I used is doing runc exec in a look parallel with runc
pause/resume in another loop, and the failure to freeze rate reduced
from 40 to 0 per minute (tested inside a VM using a busybox container
running sleep 1h, doing about 1500 pause/resumes and 650 execs per
minute), with max retries being 150 (of 1000).
This is still a game of chances, so failures are possible.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
We use github.com/pkg/errors to produce an error in many places.
One of its benefits is error comes with a stack trace.
Let's print that stack trace if --debug is set.
Example:
# ../runc --debug run -d ''
ERRO[0000] container id cannot be empty
DEBU[0000] container id cannot be empty
main.init
github.com/opencontainers/runc/utils_linux.go:28
runtime.doInit
runtime/proc.go:5652
runtime.main
runtime/proc.go:191
runtime.goexit
runtime/asm_amd64.s:1374
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
The correct way to do that conversion according to
https://pkg.go.dev/syscall#Errno is:
```
err = nil
if errno != 0 {
err = errno
}
```
In this case the error check will always report a false positive in
unix.RawSyscall(unix.SYS_SECCOMP, ...), probably nobody has faced this
problem because the code takes the other path in most of the cases.
Fixes: 7a8d7162f9 ("seccomp: prepend -ENOSYS stub to all filters")
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Currently, set -e ("exit on error") is only set before running tests.
The bad consequence is the script may fail to set up test environment
but will still run the tests.
Use "set -e -u -o pipefail" for the whole script to catch potential
issues with test setup and/or the script itself.
A few caveats:
1. We have to set RUNC_USE_SYSTEMD to an empty value if it is unset, so
that the subsequent checks like [ -z "$RUNC_USE_SYSTEMD" ] won't
trigger a "unbound variable" error. Same for ROOTLESS_TESTPATH.
2. Functions that have code like [ -f $file ] && do_something towards
the end may return 1 in case $file does not exist (as test aka [
was the last operation performed, and its exit code is returned.
This is why we had to add return 0.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>