Commit Graph

1924 Commits

Author SHA1 Message Date
Peter Hunt 6ce2d63a5d libct/init_linux: retry chdir to fix EPERM
Alas, the EPERM on chdir saga continues...

Unfortunately, the there were two releases between when https://github.com/opencontainers/runc/commit/5e0e67d76cc99d76c8228d48f38f37034503f315  was released
and when the workaround https://github.com/opencontainers/runc/pull/2712 was added.

Between this, folks started relying on the ability to have a workdir that the container user doesn't have access to.

Since this case was previously valid, we should continue support for it.

Now, we retry the chdir:
Once at the top of the function (to catch cases where the runc user has access, but container user does not)
and once after we setup user (to catch cases where the container user has access, and the runc user does not)

Add a test case for this as well.

Signed-off-by: Peter Hunt <pehunt@redhat.com>
2021-04-06 14:51:43 -04:00
Akihiro Suda c453f1a523 Merge pull request #2881 from kolyshkin/test-rand-cg
tests/int: some refactoring, fix a flake
2021-04-06 13:27:19 +09:00
Akihiro Suda d8a5f6084a Merge pull request #2885 from thaJeztah/config_missing_type
libcontainer/configs: add missing type for hooknames
2021-04-06 13:24:28 +09:00
Akihiro Suda 913b9f14e8 Merge pull request #2886 from thaJeztah/check_cleanup 2021-04-06 03:28:45 +09:00
Kir Kolyshkin 365c6282c7 Merge pull request #2888 from thaJeztah/fixup_rm_win_carry
libcontainer: rm windows pieces (carry #2700)
2021-04-03 19:10:36 -07:00
Aleksa Sarai 0d49470392 merge branch 'pr-2855'
Kir Kolyshkin (2):
  start: don't kill runc init too early
  libct/configs/validator: add some cgroup support

LGTMs: @AkihiroSuda @cyphar
Closes #2855
2021-04-03 12:41:41 +11:00
Sebastiaan van Stijn dc52ed250a libcontainer/user: remove outdated MAINTAINERS file
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-04-02 11:56:41 +02:00
Sebastiaan van Stijn 72ecf59c88 libcontainer/user: fix windows compile error
Move the unix-specific code to a file that's not compiled on
Windows.

Some of the errors (ErrUnsupported, ErrNoPasswdEntries, ErrNoGroupEntries)
are used in other parts of the code, so are moved to a non-platform
specific file.

Most of "user" is probably not useful on Windows, although it's possible
that Windows code may have to parse a passwd file, so leaving that code
for now.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-04-02 11:56:39 +02:00
Kir Kolyshkin 2515b0c2f2 libct/user: rm windows code
Commit bf749516 added these two functions, but they are only used from
Windows code. The v1 of this patch moved these functions to _windows.go
file, but after some discussion we decided to drop windows code
altogether, so this is what this patch now does.

This fixes

> libcontainer/user/user.go:64:6: func `groupFromOS` is unused (unused)
> libcontainer/user/user.go:35:6: func `userFromOS` is unused (unused)

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-04-02 11:56:37 +02:00
Kir Kolyshkin 0596f6e1e7 libcontainer/devices/device_windows.go: rm
This was initially added by commit d78ee47154 but later
moved from libcontainer/configs to libcontainer/devices by
commit 677baf22.

Looks like since commit 677baf22 and also [1]
there is no use for this, thus removing.

[1] https://github.com/containers/buildah/pull/2652

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-04-02 11:56:21 +02:00
Kir Kolyshkin b1deba8c5a libcontainer/configs/config_windows_test.go: rm
Nothing is in there, so removing.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-04-02 11:55:33 +02:00
Sebastiaan van Stijn f1586dbd7a libcontainer/configs/validate: make Validate() less DRY
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-04-02 11:41:19 +02:00
Sebastiaan van Stijn 4126b807cc libcontainer/configs: add missing type for hooknames
Commit ccdd75760c introduced the HookName type
for hooks, but only set this type on the Prestart const, but not for the
other hooks.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-04-02 11:08:24 +02:00
Kir Kolyshkin 6538f9f20a Merge pull request #2854 from thaJeztah/runc_warn_unknown_caps
capabilities: WARN, not ERROR, for unknown / unavailable capabilities
2021-04-01 18:27:57 -07:00
Mrunal Patel 8c4dca8dcb Merge pull request #2871 from masters-of-cats/pr-seccomp-pipe-hang
Ensure the seccomp pipe is being read while exporting bpf
2021-04-01 15:09:08 -07:00
Kir Kolyshkin 2dd62b3d42 libct/checkCriuFeatures: rm excessive debug
1. Remove printing criu args as now they are *always swrk 3.
2. Remove duplicated "feature check says" debug.

Before:

> DEBU[0000] Using CRIU with following args: [swrk 3]
> DEBU[0000] Using CRIU in FEATURE_CHECK mode
> DEBU[0000] Feature check says: type:FEATURE_CHECK success:true features:<mem_track:false lazy_pages:true >
> DEBU[0000] Feature check says: mem_track:false lazy_pages:true

After:

> DEBU[0000] Using CRIU in FEATURE_CHECK mode
> DEBU[0000] Feature check says: mem_track:false lazy_pages:true

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-04-01 12:57:41 -07:00
Kir Kolyshkin bed4d89f57 Merge pull request #2807 from kolyshkin/google-golang-protobuf
go.mod, libct: switch to google.golang.org/protobuf
2021-03-31 20:34:16 -07:00
Kir Kolyshkin 4ecff8d9d8 start: don't kill runc init too early
The stars can be aligned in a way that results in runc to leave a stale
bind mount in container's state directory, which manifests itself later,
while trying to remove the container, in an error like this:

> remove /run/runc/test2: unlinkat /run/runc/test2/runc.W24K2t: device or resource busy

The stale mount happens because runc start/run/exec kills runc init
while it is inside ensure_cloned_binary(). One such scenario is when
a unified cgroup resource is specified for cgroup v1, a cgroup manager's
Apply returns an error (as of commit b006f4a180), and when
(*initProcess).start() kills runc init just after it was started.

One solution is NOT to kill runc init too early. To achieve that,
amend the libcontainer/nsenter code to send a \0 byte to signal
that it is past the initial setup, and make start() (for both
run/start and exec) wait for this byte before proceeding with
kill on an error path.

While at it, improve some error messages.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-31 14:36:52 -07:00
Kir Kolyshkin b118430231 libct/configs/validator: add some cgroup support
Add some minimal validation for cgroups. The following checks
are implemented:

 - cgroup name and/or prefix (or path) is set;
 - for cgroup v1, unified resources are not set;
 - for cgroup v2, if memorySwap is set, memory is also set,
   and memorySwap > memory.

This makes some invalid configurations fail earlier (before runc init
is started), which is better.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-31 14:36:52 -07:00
Kir Kolyshkin 79a8647b81 libct/int: add TestFdLeaks
This is a very simple test that checks that container.Run do not leak
opened file descriptors.

In fact it does, so we have to add two exclusions:

1. /sys/fs/cgroup is opened once per lifetime in prepareOpenat2(),
    provided that cgroupv2 is used and openat2 is available. This
    works as intended ("it's not a bug, it's a feature").

2. ebpf program fd is leaked every time we call setDevices() for
   cgroupv2 (iow, every container.Run or container.Set leaks 1 fd).
   This needs to be fixed, thus FIXME.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-30 19:58:09 -07:00
Kir Kolyshkin b3be2b0b4f libct: close execFifo after start
Apparently, the parent never closes execFifo fd. Not a problem for runc
per se, but can be an issue for a user of libcontainer.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-30 19:58:09 -07:00
Kieron Browne 08b5279797 Make test specific to disassembleFilter function
TestPatchHugeSeccompFilterDoesNotBlock is only testing the
disassembleFilter function. There is no need to invoke PatchAndLoad
which has the side effect of loading a seccomp profile.

Co-authored-by: Danail Branekov <danailster@gmail.com>
Co-authored-by: Kieron Browne <kbrowne@vmware.com>
Signed-off-by: Kieron Browne <kbrowne@vmware.com>
Signed-off-by: Danail Branekov <danailster@gmail.com>
2021-03-30 12:31:14 +03:00
Danail Branekov 7b3e0bcf29 Ensure the scratch pipe is read during ExportBPF
There is a potential deadlock where the ExportBPF method call writes to
a pipe but the pipe is not read until after the method call returns.
ExportBPF might fill the pipe buffer, in which case it will block
waiting for a read on the other side which can't happen until the method
returns.

Here we concurrently read from the pipe into a buffer to ensure
ExportBPF will always return.

Co-authored-by: Kieron Browne <kbrowne@vmware.com>
Co-authored-by: Danail Branekov <danailster@gmail.com>
Signed-off-by: Kieron Browne <kbrowne@vmware.com>
Signed-off-by: Danail Branekov <danailster@gmail.com>
2021-03-30 12:29:35 +03:00
Kir Kolyshkin 2400e5e36e Merge pull request #2860 from kolyshkin/validate-c
fix/simplify scripts/validate-c, fix *.c formatting
2021-03-28 10:17:34 -07:00
Sebastiaan van Stijn 5fb831a0fa capabilities: WARN, not ERROR, for unknown / unavailable capabilities
This updates handling of capabilities to match the updated runtime specification,
in https://github.com/opencontainers/runtime-spec/pull/1094.

Prior to that change, the specification required runtimes to produce a (fatal)
error if a container configuration requested capabilities that could not be
granted (either the capability is "unknown" to the runtime, not supported by the
kernel version in use, or not available in the environment that the runtime
operates in).

This caused problems in situations where the runtime was running in a restricted
environment (for example, docker-in-docker), or if there is a mismatch between
the list of capabilities known by higher-level runtimes and the OCI runtime.

Some examples:

- Kernel 5.8 introduced CAP_PERFMON, CAP_BPF, and CAP_CHECKPOINT_RESTORE
  capabilities. Docker 20.10.0 ("higher level runtime") shipped with
  an updated list of capabilities, and when creating a "privileged" container,
  would determine what capabilities are known by the kernel in use, and request
  all those capabilities (by including them in the container config).
  However, runc did not yet have an updated list of capabilities, and therefore
  reject the container specification, producing an error because the new
  capabilities were "unknown".
- When running nested containers, for example, when running docker-in-docker,
  the "inner" container may be using a more recent version of docker than the
  "outer" container. In this situation, the "outer" container may be missing
  capabilities that the inner container expects to be supported (based on
  kernel version). However, starting the container would fail, because the OCI
  runtime could not grant those capabilities (them not being available in the
  environment it's running in).

WARN (but otherwise ignore) capabilities that cannot be granted
--------------------------------------------------------------------------------

This patch changes the handling to WARN (but otherwise ignore) capabilities that
are requested in the container config, but cannot be granted, alleviating higher
level runtimes to detect what capabilities are supported (by the kernel, and
in the current environment), as well as avoiding failures in situations where
the higher-level runtime is aware of capabilities that are not (yet) supported
by runc.

Impact on security
--------------------------------------------------------------------------------

Given that `capabilities` is an "allow-list", ignoring unknown capabilities does
not impose a security risk; worst case, a container does not get all requested
capabilities granted and, as a result, some actions may fail.

Backward-compatibility
--------------------------------------------------------------------------------

This change should be fully backward compatible. Higher-level runtimes that
already dynamically adjust the list of requested capabilities can continue to do
so. Runtimes that do not adjust will see an improvement (containers can start
even if some of the requested capabilities are not granted). Container processes
MAY fail (as described in "impact on security"), but users can debug this
situation either by looking at the warnings produces by the OCI runtime, or using
tools such as `capsh` / `libcap` to get the list of actual capabilities in the
container.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-26 21:23:00 +01:00
Mrunal Patel 1827254afe Merge pull request #2870 from kolyshkin/seccomp-version
libct/seccomp: remove IsEnabled
2021-03-26 11:20:55 -07:00
Mrunal Patel 547951061e Merge pull request #2835 from kolyshkin/fix-init-log-race
Fix init log forwarding race
2021-03-26 11:17:03 -07:00
Akihiro Suda 5df79d5c3d Merge pull request #2820 from dqminh/io-cgroup2-fallback
fs2: fallback to setting io.weight if io.bfq.weight
2021-03-26 18:58:51 +09:00
Kir Kolyshkin 2726146b04 runc --debug: more tests
First, add runc --debug exec test cases, very similar to those in
debug.bats but for runc exec (rather than runc run). Do not include json
tests as it is already tested in debug.bats.

Second, add logrus debug to late stages of runc init, and amend the
integration tests to check for those messages. This serves two purposes:

 - demonstrate that runc init can be amended with debug logrus which is
   properly forwarded to and logged by the parent runc create/run/exec;

 - improve the chances to catch the race fixed by the previous commit.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-25 19:19:20 -07:00
Kir Kolyshkin 201d60c51d runc run/start/exec: fix init log forwarding race
Sometimes debug.bats test cases are failing like this:

> not ok 27 global --debug to --log --log-format 'json'
> # (in test file tests/integration/debug.bats, line 77)
> #   `[[ "${output}" == *"child process in init()"* ]]' failed

It happens more when writing to disk.

This issue is caused by the fact that runc spawns log forwarding goroutine
(ForwardLogs) but does not wait for it to finish, resulting in missing
debug lines from nsexec.

ForwardLogs itself, though, never finishes, because it reads from a
reading side of a pipe which writing side is not closed. This is
especially true in case of runc create, which spawns runc init and
exits; meanwhile runc init waits on exec fifo for arbitrarily long
time before doing execve.

So, to fix the failure described above, we need to:

 1. Make runc create/run/exec wait for ForwardLogs to finish;

 2. Make runc init close its log pipe file descriptor (i.e.
    the one which value is passed in _LIBCONTAINER_LOGPIPE
    environment variable).

This is exactly what this commit does:

 1. Amend ForwardLogs to return a channel, and wait for it in start().

 2. In runc init, save the log fd and close it as late as possible.

PS I have to admit I still do not understand why an explicit close of
log pipe fd is required in e.g. (*linuxSetnsInit).Init, right before
the execve which (thanks to CLOEXEC) closes the fd anyway.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-25 19:18:55 -07:00
Kir Kolyshkin c06f999b76 libct/logs/test: refactor
- add check, checkWait, and finish helpers;
 - move test cleanup to runLogForwarding;
 - introduce and use log struct.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-25 18:58:30 -07:00
Kir Kolyshkin 688ea99e1b runc init: fix double call to ConfigureLogs
I have noticed that ConfigureLogs do not return an error in case logging
was already configured -- instead it just warns about it. So I went
ahead and changed the warning to the actual error...

... only to discover I broke things badly, because in case of runc init
logging is configured twice. The fix is to not configure logging in case
we are init.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-25 18:56:15 -07:00
Kir Kolyshkin 69ec21a12f libct/logs.ForwardLogs: use bufio.Scanner
Error handling is slightly cleaner this way.

While at it, do minor refactoring and fix error logging
in processEntry.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-25 18:56:15 -07:00
Kir Kolyshkin d38d1f9f79 libcontainer/logs: use int for Config.LogPipeFd
It does not make sense to have a string for a numeric type.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-25 18:56:15 -07:00
Kir Kolyshkin ac93746c4d libct/seccomp: rm IsEnabled
seccomp.IsEnabled is not well defined (the presence of Seccomp: field
in /proc/self/status does not tell us whether CONFIG_SECCOMP_FILTER
is enabled in the kernel; parsing all keys in /proc/self/status is a
moderate waste of resources, etc).

I traced its addition back to [1] and even in there it is not clear
what for it was added. There were never an internal user (except
for the recently added one, removed by the previous commit), and
can't find any external users (but found two copy-pastes of this
code, suffering from the same problems, see [2] and [3]).

Since it is broken and has no users, remove it.

[1] https://github.com/opencontainers/runc/pull/471
[2] https://github.com/containerd/containerd/blob/master/pkg/seccomp/seccomp_linux.go
[3] https://github.com/containers/common/blob/master/pkg/seccomp/supported.go

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-23 16:59:46 -07:00
Kir Kolyshkin ec7ca2a9d8 Merge pull request #2851 from thaJeztah/fix_build_tags
Fix build-tags in libcontainer/devices
2021-03-22 20:34:23 -07:00
Akihiro Suda 3cc9670dd4 Merge pull request #2863 from thaJeztah/runc_refactor_caps
capabilities.Caps: use a map for capability-types
2021-03-22 14:33:35 +09:00
Akihiro Suda e112c95b30 Merge pull request #2852 from thaJeztah/apparmor_once 2021-03-22 03:07:26 +09:00
Sebastiaan van Stijn 997e89420d capabilities.Caps: use a map for capability-types
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-19 11:21:08 +01:00
Kir Kolyshkin 41f466d89d nsexec.c: fix formatting for netlink defines
They were not aligned, and the last two had spaces not tabs.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-18 16:56:14 -07:00
Kir Kolyshkin 522bd64187 Fix checking C code formatting
Apparently, scripts/validate-c is not working in CI (or maybe
maintainers ignored the failures from it) -- current C code
gets some changes if we run indent on it.

This commit fixes this, simplifying things along the way.

 In particular:

1. Remove "validate" make target, add "cfmt" target that just runs
   indent on all *.c files in the repository (NOTE that *.h files
   are not included, as before).

   This may help a contributor to fix their code -- they just need
   to run "make cfmt" now instead of running "make validate" and
   copy-pasting the indent command and options from the hint.

2. Split GHA validate/misc into validate/release and validate/cfmt.
   The latter checks that the sources are not changed after "make cfmt".

3. Adds a few more options to indent. This was mostly motivated by
   trying to save the existing formatting, minimizing the amount of
   changes indent produces.

   The new options are:

   * -il0: sets the offset for goto labels to 0 (currently all labels
     but one are not indented -- let's keep it that way);

   * -ppi2: sets the indentation for nested preprocessor directives
     to 2 spaces (same as it is done in "SYS_memfd_create" defines);

   * -cp1: sets the indentation between #else / #endif and the
     following comment to 1 space.

4. Reformat the code using the new indent options.

5. Remove the now-unused script/{.validate,validate-c}.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-18 16:56:09 -07:00
Kir Kolyshkin 1948b4cee8 cloned_binary.c: rm redundant comments
Remove comments with architectures when defining SYS_memfd_create,
as they are redundant, and indent has a funny way of indenting them.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-18 16:53:44 -07:00
Kir Kolyshkin b67deb567a nsexec.c: rm a block
This block apparently does nothing except for creating
a need for additional indentation. Remove it.

While at it, break a long line in this code.

No functional change.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-17 13:08:20 -07:00
Sebastiaan van Stijn 513d89eec5 capabilities: use BOUNDING/AMBIENT instead of their alias
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-17 17:10:15 +01:00
Akihiro Suda 0ae1475066 Merge pull request #2798 from adrianreber/2021-02-08-nested-bind.mounts
Correctly restore containers with nested bind mounts
2021-03-17 12:47:21 +09:00
Sebastiaan van Stijn a608b7e725 libcontainer/apparmor: use sync.Once for AppArmor detection
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-16 15:12:55 +01:00
Sebastiaan van Stijn d6e892489f Fix build-tags in libcontainer/devices
Allows importing this package on Windows (for the types)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-14 19:11:19 +01:00
AdamKorcz 2ae5665351 Move fuzzers upstream
Signed-off-by: AdamKorcz <adam@adalogics.com>
2021-03-09 10:07:11 +00:00
Daniel Dao 8c7ece1e6d fs2: fallback to setting io.weight if io.bfq.weight
if bfq is not loaded, then io.bfq.weight is not available. io.weight
should always be available and is the next best equivalent thing.

Signed-off-by: Daniel Dao <dqminh89@gmail.com>
2021-03-05 13:55:36 +00:00
Kir Kolyshkin 97f2e351a8 go.mod, libct: bump go-criu to v5, use google.golang.org/protobuf
Switch from github.com/golang/protobuf (which appears to be obsoleted)
to google.golang.org/protobuf (which appears to be a replacement).

This needs a bump to go-criu v5.

[v2: fix debug print in criuSwrk]
[v3: switch to go-criu v5]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-03-04 08:59:55 -08:00