mirror of
https://github.com/opencontainers/runc.git
synced 2025-09-27 03:46:19 +08:00
Add dmz-vs-selinux kludge and a way to disable it
Add a workaround for a problem of older container-selinux not allowing runc to use dmz feature. If runc sees that SELinux is in enforced mode and the container's SELinux label is set, it disables dmz. Add a build tag, runc_dmz_selinux_nocompat, which disables the workaround. Newer distros that ship container-selinux >= 2.224.0 (currently CentOS Stream 8 and 9, RHEL 8 and 9, and Fedora 38+) may build runc with this build tag set to benefit from dmz working with SELinux. Document the build tag in the top-level and libct/dmz READMEs. Use the build tag in our CI builds for CentOS Stream 9 and Fedora 38, as they already has container-selinux 2.224.0 available in updates. Add a TODO to use the build tag for CentOS Stream 8 once it has container-selinux updated. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
13
.cirrus.yml
13
.cirrus.yml
@@ -57,7 +57,7 @@ task:
|
|||||||
mkdir -p -m 0700 /root/.ssh
|
mkdir -p -m 0700 /root/.ssh
|
||||||
vagrant ssh-config >> /root/.ssh/config
|
vagrant ssh-config >> /root/.ssh/config
|
||||||
guest_info_script: |
|
guest_info_script: |
|
||||||
ssh default 'sh -exc "uname -a && systemctl --version && df -T && cat /etc/os-release && go version && sestatus"'
|
ssh default 'sh -exc "uname -a && systemctl --version && df -T && cat /etc/os-release && go version && sestatus && rpm -q container-selinux"'
|
||||||
check_config_script: |
|
check_config_script: |
|
||||||
ssh default /vagrant/script/check-config.sh
|
ssh default /vagrant/script/check-config.sh
|
||||||
unit_tests_script: |
|
unit_tests_script: |
|
||||||
@@ -159,6 +159,17 @@ task:
|
|||||||
echo -e "Host localhost\n\tStrictHostKeyChecking no\t\nIdentityFile /root/.ssh/id_ed25519\n" >> /root/.ssh/config
|
echo -e "Host localhost\n\tStrictHostKeyChecking no\t\nIdentityFile /root/.ssh/id_ed25519\n" >> /root/.ssh/config
|
||||||
sed -e "s,PermitRootLogin.*,PermitRootLogin prohibit-password,g" -i /etc/ssh/sshd_config
|
sed -e "s,PermitRootLogin.*,PermitRootLogin prohibit-password,g" -i /etc/ssh/sshd_config
|
||||||
systemctl restart sshd
|
systemctl restart sshd
|
||||||
|
|
||||||
|
# Disable the dmz-vs-selinux workaround for distros that have container-selinux >= 2.224.0.
|
||||||
|
case $DISTRO in
|
||||||
|
# TODO: remove centos-stream-8.
|
||||||
|
centos-7|centos-stream-8)
|
||||||
|
# Do nothing.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo 'export EXTRA_BUILDTAGS=runc_dmz_selinux_nocompat' >> /root/.bashrc
|
||||||
|
;;
|
||||||
|
esac
|
||||||
host_info_script: |
|
host_info_script: |
|
||||||
uname -a
|
uname -a
|
||||||
# -----
|
# -----
|
||||||
|
@@ -69,6 +69,7 @@ make BUILDTAGS=""
|
|||||||
|---------------|---------------------------------------|--------------------|---------------------|
|
|---------------|---------------------------------------|--------------------|---------------------|
|
||||||
| `seccomp` | Syscall filtering using `libseccomp`. | yes | `libseccomp` |
|
| `seccomp` | Syscall filtering using `libseccomp`. | yes | `libseccomp` |
|
||||||
| `!runc_nodmz` | Reduce memory usage for CVE-2019-5736 protection by using a small C binary, [see `memfd-bind` for more details][contrib-memfd-bind]. `runc_nodmz` disables this feature and causes runc to use a different protection mechanism which will further increases memory usage temporarily during container startup. This feature can also be disabled at runtime by setting the `RUNC_DMZ=legacy` environment variable. | yes ||
|
| `!runc_nodmz` | Reduce memory usage for CVE-2019-5736 protection by using a small C binary, [see `memfd-bind` for more details][contrib-memfd-bind]. `runc_nodmz` disables this feature and causes runc to use a different protection mechanism which will further increases memory usage temporarily during container startup. This feature can also be disabled at runtime by setting the `RUNC_DMZ=legacy` environment variable. | yes ||
|
||||||
|
| `runc_dmz_selinux_nocompat` | Disables a SELinux DMZ workaround (new distros should set this). See [dmz README] for details. | no ||
|
||||||
|
|
||||||
The following build tags were used earlier, but are now obsoleted:
|
The following build tags were used earlier, but are now obsoleted:
|
||||||
- **nokmem** (since runc v1.0.0-rc94 kernel memory settings are ignored)
|
- **nokmem** (since runc v1.0.0-rc94 kernel memory settings are ignored)
|
||||||
@@ -76,6 +77,7 @@ The following build tags were used earlier, but are now obsoleted:
|
|||||||
- **selinux** (since runc v1.0.0-rc93 the feature is always enabled)
|
- **selinux** (since runc v1.0.0-rc93 the feature is always enabled)
|
||||||
|
|
||||||
[contrib-memfd-bind]: /contrib/cmd/memfd-bind/README.md
|
[contrib-memfd-bind]: /contrib/cmd/memfd-bind/README.md
|
||||||
|
[dmz README]: /libcontainer/dmz/README.md
|
||||||
|
|
||||||
### Running the test suite
|
### Running the test suite
|
||||||
|
|
||||||
|
@@ -32,6 +32,9 @@ EOF
|
|||||||
# To avoid "avc: denied { nosuid_transition }" from SELinux as we run tests on /tmp.
|
# To avoid "avc: denied { nosuid_transition }" from SELinux as we run tests on /tmp.
|
||||||
mount -o remount,suid /tmp
|
mount -o remount,suid /tmp
|
||||||
|
|
||||||
|
# Disable selinux-vs-dmz workaround as Fedora doesn't need it.
|
||||||
|
echo 'export EXTRA_BUILDTAGS=runc_dmz_selinux_nocompat' >> /root/.bashrc
|
||||||
|
|
||||||
# Prevent the "fatal: unsafe repository" git complain during build.
|
# Prevent the "fatal: unsafe repository" git complain during build.
|
||||||
git config --global --add safe.directory /vagrant
|
git config --global --add safe.directory /vagrant
|
||||||
|
|
||||||
|
@@ -457,6 +457,10 @@ func slicesContains[S ~[]E, E comparable](slice S, needle E) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isDmzBinarySafe(c *configs.Config) bool {
|
func isDmzBinarySafe(c *configs.Config) bool {
|
||||||
|
if !dmz.WorksWithSELinux(c) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Because we set the dumpable flag in nsexec, the only time when it is
|
// Because we set the dumpable flag in nsexec, the only time when it is
|
||||||
// unsafe to use runc-dmz is when the container process would be able to
|
// unsafe to use runc-dmz is when the container process would be able to
|
||||||
// race against "runc init" and bypass the ptrace_may_access() checks.
|
// race against "runc init" and bypass the ptrace_may_access() checks.
|
||||||
|
@@ -15,4 +15,16 @@ It also support all the architectures we support in runc.
|
|||||||
|
|
||||||
If the GOARCH we use for compiling doesn't support nolibc, it fallbacks to using the C stdlib.
|
If the GOARCH we use for compiling doesn't support nolibc, it fallbacks to using the C stdlib.
|
||||||
|
|
||||||
|
## SELinux compatibility issue and a workaround
|
||||||
|
|
||||||
|
Older SELinux policy can prevent runc to execute the dmz binary. The issue is
|
||||||
|
fixed in [container-selinux v2.224.0]. Yet, some older distributions may not
|
||||||
|
have the fix, so runc has a runtime workaround of disabling dmz if it finds
|
||||||
|
that SELinux is in enforced mode and the container SELinux label is set.
|
||||||
|
|
||||||
|
Distributions that have a sufficiently new container-selinux can disable the
|
||||||
|
workaround by building runc with the `runc_dmz_selinux_nocompat` build flag,
|
||||||
|
essentially allowing dmz to be used together with SELinux.
|
||||||
|
|
||||||
[nolibc-upstream]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/include/nolibc?h=v6.6-rc3
|
[nolibc-upstream]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/include/nolibc?h=v6.6-rc3
|
||||||
|
[container-selinux v2.224.0]: https://github.com/containers/container-selinux/releases/tag/v2.224.0
|
||||||
|
10
libcontainer/dmz/selinux.go
Normal file
10
libcontainer/dmz/selinux.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
//go:build runc_dmz_selinux_nocompat || !linux
|
||||||
|
|
||||||
|
package dmz
|
||||||
|
|
||||||
|
import "github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
|
||||||
|
// WorksWithSELinux tells whether runc-dmz can work with SELinux.
|
||||||
|
func WorksWithSELinux(*configs.Config) bool {
|
||||||
|
return true
|
||||||
|
}
|
28
libcontainer/dmz/selinux_compat.go
Normal file
28
libcontainer/dmz/selinux_compat.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//go:build linux && !runc_dmz_selinux_nocompat
|
||||||
|
|
||||||
|
package dmz
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WorksWithSELinux tells whether runc-dmz can work with SELinux.
|
||||||
|
//
|
||||||
|
// Older SELinux policy can prevent runc to execute the dmz binary. The issue is
|
||||||
|
// fixed in container-selinux >= 2.224.0:
|
||||||
|
//
|
||||||
|
// - https://github.com/containers/container-selinux/issues/274
|
||||||
|
// - https://github.com/containers/container-selinux/pull/280
|
||||||
|
//
|
||||||
|
// Alas, there is is no easy way to do a runtime check if dmz works with
|
||||||
|
// SELinux, so the below workaround is enabled by default. It results in
|
||||||
|
// disabling dmz in case container SELinux label is set and the selinux is in
|
||||||
|
// enforced mode.
|
||||||
|
//
|
||||||
|
// Newer distributions that have the sufficiently new container-selinux version
|
||||||
|
// can build runc with runc_dmz_selinux_nocompat build flag to disable this
|
||||||
|
// workaround (essentially allowing dmz to be used together with SELinux).
|
||||||
|
func WorksWithSELinux(c *configs.Config) bool {
|
||||||
|
return c.ProcessLabel == "" || selinux.EnforceMode() != selinux.Enforcing
|
||||||
|
}
|
Reference in New Issue
Block a user