Commit Graph

4963 Commits

Author SHA1 Message Date
Kir Kolyshkin 4d6ffa39a0 tests/int/helpers: reimplement wait_for_container
... 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>
2021-02-08 12:45:44 -08:00
Kir Kolyshkin e7052dcd83 tests/int/spec.bats: don't use HELLO_BUNDLE
All tests are run with cd to bundle directory, so
let's just use $(pwd).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-08 12:45:44 -08:00
Kir Kolyshkin 0cfc2e327d tests/int: rm teardown_running_container_inroot
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>
2021-02-08 12:45:44 -08:00
Kir Kolyshkin 78f0e4b277 tests/int: rm wait_for_container_inroot
Since commit abd0515816 it is no longed used.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-08 12:45:44 -08:00
Kir Kolyshkin 64d5702f02 tests/int: don't depend on BUSYBOX_BUNDLE var
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>
2021-02-08 12:45:44 -08:00
Aleksa Sarai 94ae7afa36 merge branch 'pr-2791'
Kir Kolyshkin (1):
  cgroupv1 freezer: thaw to increase freeze chances

LGTMs: @cyphar @dqminh
Closes #2791
2021-02-07 19:04:04 +11:00
Aleksa Sarai b4cb54c2ea merge branch 'pr-2782'
Kir Kolyshkin (2):
  ci/gha: bump golangci-lint to v1.36
  .golangci.yml: add

LGTMs: @AkihiroSuda @cyphar
Closes #2782
2021-02-05 17:46:52 +11:00
Akihiro Suda 9f1e43ea69 Merge pull request #2741 from kolyshkin/test-images 2021-02-05 15:30:43 +09:00
Akihiro Suda 072ed8779b Merge pull request #2789 from kolyshkin/error-trace 2021-02-05 15:21:56 +09:00
Kir Kolyshkin d1007b08a3 cgroupv1 freezer: thaw to increase freeze chances
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>
2021-02-04 15:06:11 -08:00
Kir Kolyshkin 1e0016cf57 Show error stack trace if --debug is set
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>
2021-02-04 11:50:21 -08:00
Mrunal Patel 19437f3a55 Merge pull request #2787 from kolyshkin/gha-fedora
ci/gha/fedora: retry vagrant up
2021-02-03 17:41:34 -08:00
Mrunal Patel c46eced395 Merge pull request #2788 from kinvolk/mauricio/fix_err_conversion
libcontainer: fix bad conversion from syscall.Errno to error
2021-02-03 17:40:52 -08:00
Aleksa Sarai 7c11557a07 merge branch 'pr-2784'
Aleksa Sarai (2):
  VERSION: back to development
  VERSION: release 1.0.0~rc93

Vote: +6 -0 #1
Closes #2784
2021-02-04 11:15:41 +11:00
Mauricio Vásquez 5c0342ba2c libcontainer: fix bad conversion from syscall.Errno to error
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>
2021-02-03 16:12:33 -05:00
Kir Kolyshkin a9e99b6da3 ci/gha/fedora: retry vagrant up
download.fedoraproject.org gives HTTP 404 at times,
breaking the CI. Let's give it another chance.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-03 10:56:00 -08:00
Aleksa Sarai f26768a820 VERSION: back to development
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-02-03 11:58:14 +11:00
Aleksa Sarai 12644e614e VERSION: release 1.0.0~rc93
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
v1.0.0-rc93
2021-02-03 11:57:49 +11:00
Kir Kolyshkin c348b98203 tests/rootless.sh: fix/ignore shellcheck warnings
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-02 16:03:52 -08:00
Kir Kolyshkin 1143759338 tests/rootless.sh: use set -e -u -o pipefail
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>
2021-02-02 16:03:52 -08:00
Kir Kolyshkin 5ab0588432 ci: untangle getting test images
This simplifies and optimizes getting container images used for tests.

Currently, we have three different ways of getting images:

1. (for hello-world) the image is in this repo under tests/integration/testdata.

2. (for busybox) download it from github (the repo that is used for
   preparing official Docker image) using curl.

3. (for debian) download from Docker hub, using skopeo and umoci.

To further complicate things, we have to do this downloading in multiple
scenarios (at least 4): locally, in github CI, from Dockefile, inside a
Vagrant VM. For each scenario, we have to install skopeo and umoci, and
those two are not yet universally available for all the distros that we
use.

Yet another complication is those images are used for tests/integration
(bats-driven tests) as well as for libcontainer/integration (go tests).
The tests in libcontainer/integration rely on busybox being available
from /busybox, and the bats tests just download the images to a
temporary location during every run.

It is also hard to support CI for other architectures, because all
the machinery for preparing images is so complicated.

This commit is an attempt to simplify and optimize getting images,
mostly by getting rid of skopeo and umoci dependencies, but also
by moving the download logic into one small shell script, which
is used from all the places.

Benefits:

 - images (if not present) are only downloaded once;
 - same images are used for both kind of tests (go and bats);
 - same images are used for local and inside-docker tests
   (because source directory is mounted into container);
 - the download logic is located within 1 simple shell script.

[v2: fix eval; more doc to get-images; print URL if curl failed]
[v3: use "slim" debian, twice as small]
[v4: fix not using $image in setup_bundle]
[v5: don't remove TESTDATA from helpers.bash]
[v6: add i386 support]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-02 16:03:29 -08:00
Kir Kolyshkin bc175ba423 tests/helpers.bash: rm GOPATH
It is not used anywhere since commit 30601efa81.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-02 11:47:06 -08:00
Aleksa Sarai 7e3c3e8c22 merge branch 'pr-2780'
Sebastiaan van Stijn (1):
  Remove "PatchAndLoad" stub as it's not used without seccomp enabled

LGTMs: @kolyshkin @cyphar
Closes #2780
2021-02-03 00:45:32 +11:00
Aleksa Sarai cc988c1036 merge branch 'pr-2774'
Kir Kolyshkin (1):
  libct/cg/fs/freezer: fix freezing race

LGTMs: @mrunalp @cyphar
Closes #2774
2021-02-02 10:25:35 +11:00
Kir Kolyshkin dc0257926a ci/gha: bump golangci-lint to v1.36
Changes: https://github.com/golangci/golangci-lint/releases

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-01 14:24:15 -08:00
Kir Kolyshkin 4d3a8d5e53 .golangci.yml: add
This is to enable seccomp build tag (some linters do use tags,
some don't).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-01 14:20:59 -08:00
Kir Kolyshkin 76ae1f5c31 libct/cg/fs/freezer: fix freezing race
Before this commit, Set() used GetState() to check the freezer state
and retry the operation if the actual state still differs from requested.
This should help with the situation when a new process (such as one
added by runc exec) is added to the container's cgroup while it's being
freezed by the kernel, but it's not working as it should.

The problem is, GetState() never returns FREEZING state, looping until
the state is either FROZEN or THAWED, so Set() does not have a chance
to repeate the freeze attempt.

As a result, the container might end up stuck in a FREEZING state,
with GetState() never returning (which in turn blocks some other
operations).

One way to fix this would be to have GetState returning FREEZING state
instead of retrying ad infinitum. It would result in changing the public
API, and no callers of GetState expects it to return this.

To fix, let's not use GetState() from Set(). Instead, read the
freezer.state file directly and act accordingly -- return success
on FROZEN, retry on FREEZING, and error out on any other (unexpected)
value.

While at it, further improve the code:
 - limit the number of retries;
 - if retries are exceeded, thaw and return an error;
 - don't retry (or read the state back) on THAW.

I played a lot with various reproducers for this bug, including

 - parallel runc execs and runc pause/resumes
 - parallel runc execs and runc --systemd-cgroup update
   (the latter performs freeze/unfreeze);
 - continuously running /bin/printf inside container
   in parallel with runc pause/resume;
 - running pthread bomb (from criu test suite) in parallel
   with runc pause/resume;

and I was not able to make freeze work 100%, meaning sometimes
runc pause fails, or runc --systemd-cgroup update produces a warning.

With that said, it's still a big improvement over the previous
state of affairs where container is stuck in FREEZING state,
and GetState() (and all its users) are also stuck.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-02-01 13:54:00 -08:00
Sebastiaan van Stijn c4bc3b080e Remove "PatchAndLoad" stub as it's not used without seccomp enabled
This function is called by `InitSeccomp`, but only when compiled
with seccomp (and cgo) enabled, so should not be needed for other
situations.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-01 22:01:59 +01:00
Kir Kolyshkin 6c85f6389e Merge pull request #2775 from cyphar/fix-build
cgroupfs: cpuset: fix broken build
2021-02-01 09:02:21 -08:00
Aleksa Sarai 4074b47975 merge branch 'pr-2636'
Kenta Tada (1):
  libcontainer/intelrdt: adjust the file mode

LGTMs: @AkihiroSuda @cyphar
Closes #2636
2021-02-01 20:50:25 +11:00
Akihiro Suda 2046f264ca Merge pull request #2755 from kolyshkin/numa-stat
libct/cg/fs: getPageUsageByNUMA: rewrite/optimize, fix panic, add more tests
2021-02-01 13:49:53 +09:00
Aleksa Sarai 6ddfaa5e95 cgroupfs: cpuset: fix broken build
The merge 6eed6e5795 broke the build because ab27e12ceb ("Implement
GetStat for cpuset cgroup.") dropped the errors import which was used by
c85cd2b325 ("libct/cg/fs/cpuset: don't parse mountinfo") and the CI
wasn't retriggered.

Fix this by just importing "github.com/pkg/errors" again.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-02-01 14:31:47 +11:00
Aleksa Sarai 091dd32dd1 merge branch 'pr-2607'
Sebastiaan van Stijn (1):
  libcontainer: move capabilities to separate package

LGTMs: @AkihiroSuda @cyphar
Closes #2607
2021-02-01 14:26:17 +11:00
Aleksa Sarai a4f2b2b0a8 merge branch 'pr-2769'
Kir Kolyshkin (2):
  ci: test with golang 1.16-rc1
  tests/int/spec.bats: fix for go 1.16

LGTMs: @AkihiroSuda @cyphar
Closes #2769
2021-02-01 11:05:49 +11:00
Aleksa Sarai 6eed6e5795 merge branch 'pr-2599'
Kir Kolyshkin (4):
  libct/cgroups/fs/cpuset: don't use MkdirAll
  libct/cg/fs/cpuset: don't parse mountinfo
  libct/cg/fs.getCgroupRoot: reuse (cached) cgroup mountinfo
  libct/cgroups/v1_utils: implement mountinfo cache

LGTMs: @AkihiroSuda @cyphar
Closes #2599
2021-02-01 11:04:11 +11:00
Kir Kolyshkin c531a6f26a Merge pull request #2750 from cyphar/seccomp-patched-bpf
seccomp: prepend -ENOSYS stub to all filters
2021-01-31 11:54:41 -08:00
Aleksa Sarai e17b96d7b4 merge branch 'pr-2773'
An Long (1):
  Makefile: add -trimpath go build flag

LGTMs: @AkihiroSuda @cyphar
Closes #2773
2021-01-30 16:50:11 +11:00
An Long ca42289658 Makefile: add -trimpath go build flag
Signed-off-by: An Long <aisk1988@gmail.com>
2021-01-30 00:51:03 +08:00
Akihiro Suda e7bd1fb10a Merge pull request #2717 from kolyshkin/check-proc-opt
libct/checkProcMounts: optimize
2021-01-29 17:32:45 +09:00
Akihiro Suda 8e062f1c53 Merge pull request #2771 from wangtianxia-sjtu/fix-readme-typo 2021-01-29 12:29:08 +09:00
wangtianxia d89c96297b Fix typo in README
Signed-off-by: wangtianxia <sometimesnaive@sjtu.edu.cn>
2021-01-29 10:09:00 +08:00
Mrunal Patel 8bbfde8f47 Merge pull request #2729 from kolyshkin/check-config
script/check-config.sh: fixes for cgroupv2 and v5.x kernels
2021-01-28 15:34:45 -08:00
Mrunal Patel b8c2093338 Merge pull request #2738 from kolyshkin/unit-verbose
ci/unit tests: decrease verbosity
2021-01-28 15:34:06 -08:00
Kir Kolyshkin b1195b7667 ci: test with golang 1.16-rc1
Courtesy of https://github.com/actions/setup-go/issues/92

[v2: update from beta1 to rc1]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-01-28 13:14:34 -08:00
Kir Kolyshkin 164e0adb58 tests/int/spec.bats: fix for go 1.16
go 1.16 has GO111MODULE=on by default, and since runtime-spec/schema
does not come with go.mod, it complains:

> runtime-spec/schema/validate.go:10:2: no required module provides package github.com/xeipuuv/gojsonschema: working directory is not part of a module

Use GO111MODULE=auto as a workaround.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-01-28 13:13:56 -08:00
Aleksa Sarai 4160d74338 seccomp: add enosys unit tests
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-01-28 23:11:28 +11:00
Aleksa Sarai 8bd19cd5f8 tests: add seccomp -ENOSYS integration test
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-01-28 23:11:25 +11:00
Aleksa Sarai 7a8d7162f9 seccomp: prepend -ENOSYS stub to all filters
Having -EPERM is the default was a fairly significant mistake from a
future-proofing standpoint in that it makes any new syscall return a
non-ignorable error (from glibc's point of view). We need to correct
this now because faccessat2(2) is something glibc critically needs to
have support for, but they're blocked on container runtimes because we
return -EPERM unconditionally (leading to confusion in glibc). This is
also a problem we're probably going to keep running into in the future.

Unfortunately there are several issues which stop us from having a clean
solution to this problem:

 1. libseccomp has several limitations which require us to emulate
    behaviour we want:

    a. We cannot do logic based on syscall number, meaning we cannot
       specify a "largest known syscall number";
    b. libseccomp doesn't know in which kernel version a syscall was
       added, and has no API for "minimum kernel version" so we cannot
       simply ask libseccomp to generate sane -ENOSYS rules for us.
    c. Additional seccomp rules for the same syscall are not treated as
       distinct rules -- if rules overlap, seccomp will merge them. This
       means we cannot add per-syscall -EPERM fallbacks;
    d. There is no inverse operation for SCMP_CMP_MASKED_EQ;
    e. libseccomp does not allow you to specify multiple rules for a
       single argument, making it impossible to invert OR rules for
       arguments.

 2. The runtime-spec does not have any way of specifying:

    a. The errno for the default action;
    b. The minimum kernel version or "newest syscall at time of profile
       creation"; nor
    c. Which syscalls were intentionally excluded from the allow list
       (weird syscalls that are no longer used were excluded entirely,
       but Docker et al expect those syscalls to get EPERM not ENOSYS).

 3. Certain syscalls should not return -ENOSYS (especially only for
    certain argument combinations) because this could also trigger glibc
    confusion. This means we have to return -EPERM for certain syscalls
    but not as a global default.

 4. There is not an obvious (and reasonable) upper limit to syscall
    numbers, so we cannot create a set of rules for each syscall above
    the largest syscall number in libseccomp. This means we must handle
    inverse rules as described below.

 5. Any syscall can be specified multiple times, which can make
    generation of hotfix rules much harder.

As a result, we have to work around all of these things by coming up
with a heuristic to stop the bleeding. In the future we could hopefully
improve the situation in the runtime-spec and libseccomp.

The solution applied here is to prepend a "stub" filter which returns
-ENOSYS if the requested syscall has a larger syscall number than any
syscall mentioned in the filter. The reason for this specific rule is
that syscall numbers are (roughly) allocated sequentially and thus newer
syscalls will (usually) have a larger syscall number -- thus causing our
filters to produce -ENOSYS if the filter was written before the syscall
existed.

Sadly this is not a perfect solution because syscalls can be added
out-of-order and the syscall table can contain holes for several
releases. Unfortuntely we do not have a nicer solution at the moment
because there is no library which provides information about which Linux
version a syscall was introduced in. Until that exists, this workaround
will have to be good enough.

The above behaviour only happens if the default action is a blocking
action (in other words it is not SCMP_ACT_LOG or SCMP_ACT_ALLOW). If the
default action is permissive then we don't do any patching.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-01-28 23:11:22 +11:00
Kir Kolyshkin 5ef136ff78 Merge pull request #2763 from zhsj/fix-32
Fix int overflow in test on 32 bit system
2021-01-27 11:37:33 -08:00
Aleksa Sarai 346f87fec1 merge branch 'pr-2715'
Kir Kolyshkin (3):
  tests/int/mounts.bats: cleanup
  tests/int/mount.bats: reformat
  runc run: resolve tmpfs mount dest in container scope

LGTMs: @AkihiroSuda @cyphar
Closes #2715
2021-01-27 21:50:11 +11:00