Commit Graph

2774 Commits

Author SHA1 Message Date
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
Kir Kolyshkin fe73f1a9ab libct/cap: switch to lazy init
A map which is created in func init is only used by capSlice, which is
only used by New, which is only used by runc init. Switch to lazy init
to slightly save on startup time.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-12-02 13:18:10 -08:00
Kir Kolyshkin cdee1b386f libct/cap: preallocate slices
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-12-02 13:18:10 -08:00
lfbzhm 119111a0df libct/cg: add test for remove a non-existent dir in a ro mount point
Signed-off-by: lfbzhm <lifubang@acmcoder.com>
2024-11-14 23:58:35 +00:00
Kir Kolyshkin ba3d026e52 libct/cg: RemovePath: improve comments
Let's explain in greater details what's happening here and why.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-11-11 23:17:42 -08:00
Kir Kolyshkin 12e06a7c4f libct/cg: RemovePath: simplify logic
If the sub-cgroup RemovePath has failed for any reason, return the
error right away. This way, we don't have to check for err != nil
before retrying rmdir.

This is a cosmetic change and should not change any functionality.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-11-11 23:15:01 -08:00
Kir Kolyshkin db59489b68 runc delete: fix for rootless cgroup + ro cgroupfs
An issue with runc 1.2.0 was reported to buildkit, in which
runc delete returns with an error, with the log saying:

> unable to destroy container: unable to remove container's cgroup: open /sys/fs/cgroup/snschvixiy3s74w74fjantrdg: no such file or directory

Apparently, what happens is runc is running with no cgroup access
(because /sys/fs/cgroup is mounted read-only). In this case error to
create a cgroup path (in runc create/run) is ignored, but cgroup removal
(in runc delete) is not.

This is caused by commit d3d7f7d, which changes the cgroup removal
logic in RemovePath. In the current code, if the initial rmdir has
failed (in this case with EROFS), but the subsequent os.ReadDir returns
ENOENT, it is returned (instead of being ignored -- as the path does not
exist and so there is nothing to remove).

Here is the minimal fix for the issue.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-11-11 23:12:32 -08:00
lfbzhm 3a099738ed Merge pull request #4511 from kolyshkin/rm-internal-testutil
ci: rm "skip on CentOS 7" kludges
2024-11-09 10:14:25 +08:00
Kir Kolyshkin 9cb59b4659 ci: rm "skip on CentOS 7" kludges
We no longer test on CentOS 7.

Remove the internal/testutil package as it has no other uses.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-11-07 13:16:16 -08:00
Aleksa Sarai 9bc42d61bb dmz: overlay: set xino=off to disable dmesg spam
If /run/runc and /usr/bin are on different filesystems, overlayfs may
enable the xino feature which results in the following log message:

  kernel: overlayfs: "xino" feature enabled using 3 upper inode bits.

Each time we have to protect /proc/self/exe. So disable xino to remove
the log message (we don't care about the inode numbers of the files
anyway).

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-11-04 21:01:06 +11:00
Akihiro Suda 519a3f1d5c Merge pull request #4357 from kolyshkin/update-swap-v2
runc update: fix updating swap for cgroup v2
2024-11-02 01:54:00 +09:00
Rodrigo Campos bb6aeedaec Merge pull request #4440 from yangzhao02/main
Terminate execution for criu that does not meet version requirements
2024-11-01 15:04:03 +01:00
Kir Kolyshkin 5586d7caa1 libct: rm obsoleted comment
This was added by commit f2f16213e when runc-dmz was still a thing.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-29 17:11:56 -07:00
Kir Kolyshkin 8cc7375447 libct: fix a comment
There is a typo in the comment (ClonedBinary should be CloneBinary), and
the code has changed a bit since then, and it makes more sense to refer
to CloneSelfExe now.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-29 16:57:42 -07: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
Rodrigo Campos 4ad9f7fd36 Merge pull request #4432 from kolyshkin/exec-bench
libct/int: add exec benchmark
2024-10-25 10:48:26 +02:00
lifubang c78f3f2ea0 libct/nsenter: become root after joining userns
Containerd pre-creates userns and netns before calling runc, which
results in the current code not working when SELinux is enabled,
resulting in the following error:

> runc create failed: unable to start container process: error during
container init: error mounting "mqueue" to rootfs at "/dev/mqueue":
setxattr /path/to/rootfs/dev/mqueue: operation not permitted

The solution is to become root in the user namespace right after
we join it.

Fixes #4466.

Co-authored-by: Wei Fu <fuweid89@gmail.com>
Co-authored-by: Kir Kolyshkin <kolyshkin@gmail.com>
Co-authored-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: lifubang <lifubang@acmcoder.com>
2024-10-25 13:40:49 +08:00
Kir Kolyshkin 1e674098f5 libct/int: add exec benchmark
This is a benchmark which checks how fast we can execute /bin/true
inside a container.

Results from my machine are below. As you can see, in default setup
about 70% of exec time is spent for CVE-2019-5736 (copying runc binary),
and using either RUNC_DMZ=true or memfd-bind helps a lot.

This can also be used for profiling (using -test.cpuprofile option).

=== Default setup ===

[kir@kir-tp1 integration]$ sudo ./integration.test -test.run xxx -test.v -test.benchtime 5s -test.count 5 -test.bench . .
goos: linux
goarch: amd64
pkg: github.com/opencontainers/runc/libcontainer/integration
cpu: 12th Gen Intel(R) Core(TM) i7-12800H
BenchmarkExecTrue
BenchmarkExecTrue-20    	     327	  24475677 ns/op
BenchmarkExecTrue-20    	     244	  25242718 ns/op
BenchmarkExecTrue-20    	     232	  26187174 ns/op
BenchmarkExecTrue-20    	     237	  26780030 ns/op
BenchmarkExecTrue-20    	     318	  18487219 ns/op
PASS

=== With DMZ enabled ===

[kir@kir-tp1 integration]$ sudo -E RUNC_DMZ=true ./integration.test -test.run xxx -test.v -test.benchtime 5s -test.count 5 -test.bench . .
goos: linux
goarch: amd64
pkg: github.com/opencontainers/runc/libcontainer/integration
cpu: 12th Gen Intel(R) Core(TM) i7-12800H
BenchmarkExecTrue
BenchmarkExecTrue-20    	     694	   8263744 ns/op
BenchmarkExecTrue-20    	     778	   8483228 ns/op
BenchmarkExecTrue-20    	     784	   8456018 ns/op
BenchmarkExecTrue-20    	     732	   8160239 ns/op
BenchmarkExecTrue-20    	     769	   8236972 ns/op
PASS

=== With memfd-bind ===

[kir@kir-tp1 integration]$ sudo systemctl start  memfd-bind@$(systemd-escape -p $PWD/integration.test)
[kir@kir-tp1 integration]$ sudo ./integration.test -test.run xxx -test.v -test.benchtime 5s -test.count 5 -test.bench . .
goos: linux
goarch: amd64
pkg: github.com/opencontainers/runc/libcontainer/integration
cpu: 12th Gen Intel(R) Core(TM) i7-12800H
BenchmarkExecTrue
BenchmarkExecTrue-20    	     800	   7538839 ns/op
BenchmarkExecTrue-20    	     717	   7424755 ns/op
BenchmarkExecTrue-20    	     848	   7747787 ns/op
BenchmarkExecTrue-20    	     800	   7668740 ns/op
BenchmarkExecTrue-20    	     751	   7304373 ns/op
PASS

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-24 13:39:26 -07:00
Kir Kolyshkin cb20148703 libct/int: use testing.TB for utils
...so that they can be used for benchmarks, too.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-24 13:39:26 -07:00
Kir Kolyshkin 732806e24c runc update: fix updating swap for cgroup v2
This allows to do

	runc update $ID --memory=-1 --memory-swap=$VAL

for cgroup v2, i.e. set memory to unlimited and swap to a specific
value.

This was not possible because ConvertMemorySwapToCgroupV2Value rejected
memory=-1 ("unlimited"). In a hindsight, it was a mistake, because if
memory limit is unlimited, we should treat memory+swap limit as just swap
limit.

Revise the unit test; add description to each case.

Fixes: c86be8a2 ("cgroupv2: fix setting MemorySwap")
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-22 23:51:23 -07:00
Kir Kolyshkin cb9f3d6d14 libct/cg: improve ConvertMemorySwapToCgroupV2Value
Improve readability of ConvertMemorySwapToCgroupV2Value by switching
from a bunch of if statements to a switch, and adding a comment
describing each case.

No functional change.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-22 23:51:23 -07:00
Kir Kolyshkin eb2ff52ace libct: rm x/sys/execabs usage
Since Go 1.19, the same functionality is there in os/exec package.
As we require go 1.22 now, there's no need to have this.

This basically reverts commit 9258eac0 ("libct/start: use execabs for
newuidmap lookup").

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-22 23:45:18 -07:00
lfbzhm e669926691 fix an error caused by fd reuse race when starting runc init
There is a race situation when we are opening a file, if there is a
small fd was closed at that time, maybe it will be reused by safeExe.
Because of Go stdlib fds shuffling bug, if the fd of safeExe is too
small, go stdlib will dup3 it to another fd, or dup3 a other fd to this
fd, then it will cause the fd type cmd.Path refers to a random path,
and it can lead to an error "permission denied" when starting the process.
Please see #4294 and <https://github.com/golang/go/issues/61751>.
So we should not use the original fd of safeExe, but use the fd after
shuffled by Go stdlib. Because Go stdlib will guarantee this fd refers to
the correct file.

Signed-off-by: lfbzhm <lifubang@acmcoder.com>
2024-10-21 06:53:44 +00:00
Akihiro Suda ca8ca3ce07 Merge pull request #4448 from cyphar/cloned-binary-overlayfs
dmz: use overlayfs to write-protect /proc/self/exe if possible
2024-10-21 04:11:33 +09:00
Akihiro Suda 08faf15106 Merge pull request #4429 from kolyshkin/cap-load
libct/cap: no need to load capabilities
2024-10-21 04:09:07 +09: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
Kir Kolyshkin b5bdf592f2 libct: rm initWaiter
This initWaiter logic was introduced by commit 4ecff8d9, but since the logic of
/proc/self/exe was moved out of runc init in commit 0e9a335, this
seems unnecessary to have initWaiter.

Remove it.

This essentially reverts commit 4ecff8d9.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-17 08:05:42 -07:00
lifubang 9fa324c479 dmz: cloned binary: set +x permissions when creating regular tmpfile
While we did set +x when "sealing" regular temporary files, the "is
executable" checks were done before then and would thus fail, causing
the fallback to not work properly.

So just set +x after we create the file. We already have a O_RDWR handle
open when we do the chmod so we won't get permission issues when writing
to the file.

Fixes: e089db3b4a ("dmz: add fallbacks to handle noexec for O_TMPFILE and mktemp()")

Signed-off-by: lifubang <lifubang@acmcoder.com>
2024-10-14 17:48:18 +08:00
yangzhao.hjh 324fcea4ec Terminate execution for criu that does not meet version requirements
Signed-off-by: yangzhao.hjh <yangzhao.hjh@alibaba-inc.com>
2024-10-11 09:56:07 +08:00
Kir Kolyshkin eff6f049bc libct/cap: no need to load capabilities
We are not really interested in the capabilities of the current process,
so there is no need to load those.

This results in some performance improvement since now the capability
package don't have to parse /proc/self/status.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-09 12:08:44 -07:00
Sebastiaan van Stijn 9b60a93cf3 libcontainer/userns: migrate to github.com/moby/sys/userns
The userns package was moved to the moby/sys/userns module
at commit 3778ae603c.

This patch deprecates the old location, and adds it as an alias
for the moby/sys/userns package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-09 22:20:25 +08:00
Kir Kolyshkin f2d56241d8 Merge pull request #4405 from amghazanfari/main
replace strings.SplitN with strings.Cut
2024-10-04 14:01:23 -07:00
Kir Kolyshkin 13a6f56097 runc run: fix mount leak
When preparing to mount container root, we need to make its parent mount
private (i.e. disable propagation), otherwise the new in-container
mounts are leaked to the host.

To find a parent mount, we use to read mountinfo and find the longest
entry which can be a parent of the container root directory.

Unfortunately, due to kernel bug in all Linux kernels older than v5.8
(see [1], [2]), sometimes mountinfo can't be read in its entirety. In
this case, getParentMount may occasionally return a wrong parent mount.

As a result, we do not change the mount propagation to private, and
container mounts are leaked.

Alas, we can not fix the kernel, and reading mountinfo a few times to
ensure its consistency (like it's done in, say, Kubernetes) does not
look like a good solution for performance reasons.

Fortunately, we don't need mountinfo. Let's just traverse the directory
tree, trying to remount it private until we find a mount point (any
error other than EINVAL means we just found it).

Fixes issue 2404.

[1]: https://github.com/kolyshkin/procfs-test
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f6c61f96f2d97cbb5f
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-10-02 13:58:27 -07:00
Amir M. Ghazanfari faffe1b9ee replace strings.SplitN with strings.Cut
Signed-off-by: Amir M. Ghazanfari <a.m.ghazanfari76@gmail.com>
2024-09-28 10:02:21 +03:30
Stavros Panakakis 1be06760ed libcontainer/cgroups/fs: remove todo since strings.Fields performs well
Initially, this was a commit to switch from strings.Fields to
strings.SplitN in getCpuUsageBreakdown, since strings.Fields
was probably slower than strings.SplitN in some old Go versions.

Afterwards, strings.Cut was also considered for potential
speed improvements.

After writing a benchmark test, we learned that:
 - strings.Fields performance is now adequate;
 - strings.SplitN is slower than strings.Fields;
 - strings.Cut had <5% performance gain from strings.Fields;

So, remove the TODO and keep the benchmark test.

Signed-off-by: Stavros Panakakis <stavrospanakakis@gmail.com>
2024-09-26 12:34:32 +03:00
Kir Kolyshkin 7a449109f3 libct/README: simplify example, rm inheritable caps
The example is too long since it lists too many capabilities.
Simplify it, leaving only two capabilities.

Also, remove ambient capabilities from the set. Inheritable capabilities
were removed earlier by commit 98fe566c, but ambient capabilities can't
be raised without inheritable ones.

Fixes: 98fe566c
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-25 21:48:29 -07:00
Kir Kolyshkin 0de1953333 runc spec, libct/int: do not add ambient capabilities
Commit 98fe566c removed inheritable capabilities from the example spec
(used by runc spec) and from the libcontainer/integration test config,
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 (both bats-based and libct/int tests will fail).

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

Fixes: 98fe566c ("runc: do not set inheritable capabilities")
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-25 21:48:29 -07:00
Kir Kolyshkin 47756ed7ef Merge pull request #4410 from lifubang/feat-add-ErrCgroupNotExist
Add ErrCgroupNotExist
2024-09-24 11:08:24 -07:00
lifubang 10c951e335 add ErrCgroupNotExist
For some rootless container, runc has no access to cgroup,
But the container is still running. So we should return the
`ErrNotRunning` and `ErrCgroupNotExist` error seperatlly.

Signed-off-by: lifubang <lifubang@acmcoder.com>
2024-09-23 23:27:35 +00: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 b1449fd510 libct: use Namespaces.IsPrivate more
In these cases, this is exactly what we want to find out.

Slightly improves performance and readability.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-17 22:49:29 -07:00
Kir Kolyshkin 15904913c2 Merge pull request #4397 from rafaelroquetto/main
Upgrade Cilium's eBPF library version to 0.16
2024-09-13 18:22:49 -07:00
Aleksa Sarai 646efe70b1 utils: mkdirall: mask silently ignored mode bits to match os.MkdirAll
It turns out that the suid and sgid mode bits are silently ignored by
Linux (though the sticky bit is honoured), and some users are requesting
mode bits that are ignored. While returning an error (as securejoin
does) makes some sense, this is a regression.

Ref: https://github.com/cyphar/filepath-securejoin/issues/23
Fixes: dd827f7b71 ("utils: switch to securejoin.MkdirAllHandle")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-09-13 23:34:33 +10:00
Rafael Roquetto 216175a9ca Upgrade Cilium's eBPF library version to 0.16
Signed-off-by: Rafael Roquetto <rafael.roquetto@grafana.com>
2024-09-12 11:13:21 -06:00
Kir Kolyshkin a31efe7045 libct/seccomp/patchbpf: use binary.NativeEndian
It is available since Go 1.21 and is defined during compile time
(i.e. based on GOARCH during build).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-09-11 22:06:58 -07:00
Akihiro Suda e8e8c029c7 Merge pull request #4393 from cyphar/mkdirall-inroot-securejoin
utils: switch to securejoin.MkdirAllHandle
2024-09-12 14:04:36 +09: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
Aleksa Sarai dd827f7b71 utils: switch to securejoin.MkdirAllHandle
filepath-securejoin has a bunch of extra hardening features and is very
well-tested, so we should use it instead of our own homebrew solution.

A lot of rootfs_linux.go callers pass a SecureJoin'd path, which means
we need to keep the wrapper helpers in utils, but at least the core
logic is no longer in runc. In future we will want to remove this dodgy
logic and just use file handles for everything (using libpathrs,
ideally).

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-09-03 23:06:47 +10:00
Aleksa Sarai 63c2908164 rootfs: try to scope MkdirAll to stay inside the rootfs
While we use SecureJoin to try to make all of our target paths inside
the container safe, SecureJoin is not safe against an attacker than can
change the path after we "resolve" it.

os.MkdirAll can inadvertently follow symlinks and thus an attacker could
end up tricking runc into creating empty directories on the host (note
that the container doesn't get access to these directories, and the host
just sees empty directories). However, this could potentially cause DoS
issues by (for instance) creating a directory in a conf.d directory for
a daemon that doesn't handle subdirectories properly.

In addition, the handling for creating file bind-mounts did a plain
open(O_CREAT) on the SecureJoin'd path, which is even more obviously
unsafe (luckily we didn't use O_TRUNC, or this bug could've allowed an
attacker to cause data loss...). Regardless of the symlink issue,
opening an untrusted file could result in a DoS if the file is a hung
tty or some other "nasty" file. We can use mknodat to safely create a
regular file without opening anything anyway (O_CREAT|O_EXCL would also
work but it makes the logic a bit more complicated, and we don't want to
open the file for any particular reason anyway).

libpathrs[1] is the long-term solution for these kinds of problems, but
for now we can patch this particular issue by creating a more restricted
MkdirAll that refuses to resolve symlinks and does the creation using
file descriptors. This is loosely based on a more secure version that
filepath-securejoin now has[2] and will be added to libpathrs soon[3].

[1]: https://github.com/openSUSE/libpathrs
[2]: https://github.com/cyphar/filepath-securejoin/releases/tag/v0.3.0
[3]: https://github.com/openSUSE/libpathrs/issues/10

Fixes: CVE-2024-45310
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-09-03 02:34:13 +10:00
Kir Kolyshkin 606257c6e1 Bump golangci-lint to v1.60, fix new warnings
The warnings fixed were:

libcontainer/configs/config_test.go:205:12: printf: non-constant format string in call to (*testing.common).Errorf (govet)
		t.Errorf(fmt.Sprintf("Expected error to not occur but it was %+v", err))
		         ^
libcontainer/cgroups/fs/blkio_test.go:481:13: printf: non-constant format string in call to (*testing.common).Errorf (govet)
			t.Errorf(fmt.Sprintf("test case '%s' failed unexpectedly: %s", testCase.desc, err))
			         ^
libcontainer/cgroups/fs/blkio_test.go:595:13: printf: non-constant format string in call to (*testing.common).Errorf (govet)
			t.Errorf(fmt.Sprintf("test case '%s' failed unexpectedly: %s", testCase.desc, err))
			         ^

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2024-08-14 20:39:15 +08:00