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>
The logic for how we create mountpoints is spread over each mountpoint
preparation function, when in reality the behaviour is pretty uniform
with only a handful of exceptions. So just move it all to one function
that is easier to understand.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Add this new make variable so users can specify build information
without modifying the runc version nor the source code.
Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
(cherry picked from commit cc2078ccdd)
This reverts commit 9d9273c926.
This commit broke the build for several other projects (see comments
here: https://github.com/opencontainers/runc/pull/4270, after the merge)
and we don't really need this to be able to set the version without
changing the file.
With this commit reverted, we can still run:
make VERSION="1.2.3"
and it just works. It doesn't take it from an env variable, but that is
what broke all the other projects (VERSION is just too generic as an env
var, especially for a project like runc that is embedded in many
others).
Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
(cherry picked from commit f4cc3d8313)
As of commit 096e6f88f0 we are ready for Go 1.23.
All that's left to do is:
- Cirrus CI: switch from Go 1.21 to Go 1.22;
- GHA CI: drop go 1.21, add 1.23 to test matrix;
- Dockerfile: switch from Go 1.21.x to 1.22.x.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(This is a cherry-pick of cdff09ab87 but
modified so that changes like 8e8b136c49 and a60933bb24 don't also
need to be backported. Ideally we would backport the entire "remove all
mount logic from nsexec" series, but that would be a bit too much.)
Our previous test for whether we can mount on top of /proc incorrectly
assumed that it would only be called with bind-mount sources. This meant
that having a non bind-mount entry for a pseudo-filesystem (like
overlayfs) with a dummy source set to /proc on the host would let you
bypass the check, which could easily lead to security issues.
In addition, the check should be applied more uniformly to all mount
types, so fix that as well. And add some tests for some of the tricky
cases to make sure we protect against them properly.
Fixes: 331692baa7 ("Only allow proc mount if it is procfs")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(This is a backport of b18d052bb83cbf0a6ad79aa1e79d5c9f75eddda7.)
Remove CentOS 7 as it is EOL.
Add back RHEL 8 clone (CentOS Stream 8 was removed by commit
40bb9c468e).
Switch from CentOS Stream 9 to Almalinux 9.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
I used script/keyring_validate.sh, which gave me this error:
> [*] User cyphar in runc.keyring is not a maintainer!
Apparently, when gnupg 2.4.1+ sees a fresh install (i.e. no ~/.gnupg
directory), it configures itself to use keyboxd instead of keyring
files, and when just silently ignores options like --keyring and
--no-default-keyring, working with keyboxd all the time.
The only way I found to make it not use keyboxd is to set --homedir.
Let's do that when we explicitly want a separate keyring.
Similar change is made to script/release_key.sh.
Also, change "--import --import-options=show-only" to "--show-keys"
which is a shortcut. When using this, there is no need to protect
the default keyring since this command does not read or modify it.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 760105ab11)
Signed-off-by: lifubang <lifubang@acmcoder.com>
Now when Go 1.22.4 is out it should no longer be a problem.
Leave Go 1.21 for CentOS testing (CentOS 7 and 8 have older glibc)
and Dockerfile (Debian 11 have older glibc).
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit a3302f2054)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Go 1.23 includes a fix (https://go.dev/cl/587919) so go1.23.x can be
used. This fix is also backported to 1.22.4, so go1.22.x can also be
used (when x >= 4). Finally, for glibc >= 2.32 it doesn't really matter.
Add a note about Go 1.22.x > 1.22.4 to README as well.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit e660ef61a5)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Note that github-actions output format is deprecated and no longer supported,
and it is also no longer needed since setup-go problem matcher already
handles default golangci-lint output format ("colored-line-number").
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit f452f667c0)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Go 1.23 tightens access to internal symbols, and even puts runc into
"hall of shame" for using an internal symbol (recently added by commit
da68c8e3). So, while not impossible, it becomes harder to access those
internal symbols, and it is a bad idea in general.
Since Go 1.23 includes https://go.dev/cl/588076, we can clean the
internal rlimit cache by setting the RLIMIT_NOFILE for ourselves,
essentially disabling the rlimit cache.
Once Go 1.22 is no longer supported, we will remove the go:linkname hack.
(cherry picked from commit 584afc6756)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
It is past EOL and has been removed from GCE public images.
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 40bb9c468e)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>