Skip to content

Commit 1950892

Browse files
committed
merge #4174 into opencontainers/runc:main
Rodrigo Campos (3): Makefile: Fix runc-dmz removal contrib/cmd/memfd-bind: Mention runc-dmz needs RUNC_DMZ=true libct/dmz: Require RUNC_DMZ=true to opt-in LGTMs: AkihiroSuda cyphar
2 parents 109a7a0 + fc76b13 commit 1950892

File tree

7 files changed

+37
-28
lines changed

7 files changed

+37
-28
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ recvtty sd-helper seccompagent fs-idmap memfd-bind pidfd-kill remap-rootfs:
7979

8080
.PHONY: clean
8181
clean:
82-
rm -f runc runc-* libcontainer/dmz/runc-dmz
82+
rm -f runc runc-* libcontainer/dmz/binary/runc-dmz
8383
rm -f contrib/cmd/recvtty/recvtty
8484
rm -f contrib/cmd/sd-helper/sd-helper
8585
rm -f contrib/cmd/seccompagent/seccompagent

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ make BUILDTAGS=""
6868
| Build Tag | Feature | Enabled by Default | Dependencies |
6969
|---------------|---------------------------------------|--------------------|---------------------|
7070
| `seccomp` | Syscall filtering using `libseccomp`. | yes | `libseccomp` |
71-
| `!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 ||
71+
| `!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 **experimental feature** and causes runc to use a different protection mechanism which will further increases memory usage temporarily during container startup. To enable this feature you also need to set the `RUNC_DMZ=true` environment variable. | yes ||
7272
| `runc_dmz_selinux_nocompat` | Disables a SELinux DMZ workaround (new distros should set this). See [dmz README] for details. | no ||
7373

7474
The following build tags were used earlier, but are now obsoleted:

contrib/cmd/memfd-bind/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ much memory usage they can use:
3636

3737
* `runc-dmz` is (depending on which libc it was compiled with) between 10kB and
3838
1MB in size, and a copy is created once per process spawned inside a
39-
container by runc (both the pid1 and every `runc exec`). There are
40-
circumstances where using `runc-dmz` will fail in ways that runc cannot
41-
predict ahead of time (such as restrictive LSMs applied to containers), in
42-
which case users can disable it with the `RUNC_DMZ=legacy` setting.
43-
`runc-dmz` also requires an additional `execve` over the other options,
44-
though since the binary is so small the cost is probably not even noticeable.
39+
container by runc (both the pid1 and every `runc exec`). The `RUNC_DMZ=true`
40+
environment variable needs to be set to opt-in. There are circumstances where
41+
using `runc-dmz` will fail in ways that runc cannot predict ahead of time (such
42+
as restrictive LSMs applied to containers). `runc-dmz` also requires an
43+
additional `execve` over the other options, though since the binary is so small
44+
the cost is probably not even noticeable.
4545

4646
* The classic method of making a copy of the entire `runc` binary during
4747
container process setup takes up about 10MB per process spawned inside the

libcontainer/dmz/dmz_linux.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77
"bytes"
88
"debug/elf"
99
"embed"
10+
"fmt"
1011
"os"
12+
"strconv"
1113
"sync"
1214

1315
"github.com/sirupsen/logrus"
@@ -43,11 +45,19 @@ var (
4345
// If the runc-dmz binary is not embedded into the runc binary, Binary will
4446
// return ErrNoDmzBinary as the error.
4547
func Binary(tmpDir string) (*os.File, error) {
46-
// Setting RUNC_DMZ=legacy disables this dmz method.
47-
if os.Getenv("RUNC_DMZ") == "legacy" {
48-
logrus.Debugf("RUNC_DMZ=legacy set -- switching back to classic /proc/self/exe cloning")
48+
// Only RUNC_DMZ=true enables runc_dmz.
49+
runcDmz := os.Getenv("RUNC_DMZ")
50+
if runcDmz == "" {
51+
logrus.Debugf("RUNC_DMZ is not set -- switching back to classic /proc/self/exe cloning")
4952
return nil, ErrNoDmzBinary
5053
}
54+
if dmzEnabled, err := strconv.ParseBool(runcDmz); err == nil && !dmzEnabled {
55+
logrus.Debugf("RUNC_DMZ is false -- switching back to classic /proc/self/exe cloning")
56+
return nil, ErrNoDmzBinary
57+
} else if err != nil {
58+
return nil, fmt.Errorf("parsing RUNC_DMZ: %w", err)
59+
}
60+
5161
runcDmzBinaryOnce.Do(func() {
5262
runcDmzBinary, _ = runcDmzFs.ReadFile("binary/runc-dmz")
5363
// Verify that our embedded binary has a standard ELF header.

tests/integration/exec.bats

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,14 @@ function check_exec_debug() {
323323
[ "$status" -eq 0 ]
324324
}
325325

326-
@test "RUNC_DMZ=legacy runc exec [execve error]" {
326+
@test "runc exec [execve error]" {
327327
cat <<EOF >rootfs/run.sh
328328
#!/mmnnttbb foo bar
329329
sh
330330
EOF
331331
chmod +x rootfs/run.sh
332-
RUNC_DMZ=legacy runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
333-
RUNC_DMZ=legacy runc exec -t test_busybox /run.sh
332+
runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
333+
runc exec -t test_busybox /run.sh
334334
[ "$status" -ne 0 ]
335335

336336
# After the sync socket closed, we should not send error to parent

tests/integration/run.bats

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,20 @@ function teardown() {
127127
[ "${lines[0]}" = "410" ]
128128
}
129129

130-
@test "runc run [runc-dmz]" {
131-
runc --debug run test_hello
130+
@test "RUNC_DMZ=true runc run [runc-dmz]" {
131+
RUNC_DMZ=true runc --debug run test_hello
132132
[ "$status" -eq 0 ]
133133
[[ "$output" = *"Hello World"* ]]
134134
# We use runc-dmz if we can.
135135
[[ "$output" = *"runc-dmz: using runc-dmz"* ]]
136136
}
137137

138-
@test "runc run [cap_sys_ptrace -> /proc/self/exe clone]" {
138+
@test "RUNC_DMZ=true runc run [cap_sys_ptrace -> /proc/self/exe clone]" {
139139
# Add CAP_SYS_PTRACE to the bounding set, the minimum needed to indicate a
140140
# container process _could_ get CAP_SYS_PTRACE.
141141
update_config '.process.capabilities.bounding += ["CAP_SYS_PTRACE"]'
142142

143-
runc --debug run test_hello
143+
RUNC_DMZ=true runc --debug run test_hello
144144
[ "$status" -eq 0 ]
145145
[[ "$output" = *"Hello World"* ]]
146146
if [ "$EUID" -ne 0 ] && is_kernel_gte 4.10; then
@@ -154,8 +154,8 @@ function teardown() {
154154
fi
155155
}
156156

157-
@test "RUNC_DMZ=legacy runc run [/proc/self/exe clone]" {
158-
RUNC_DMZ=legacy runc --debug run test_hello
157+
@test "runc run [/proc/self/exe clone]" {
158+
runc --debug run test_hello
159159
[ "$status" -eq 0 ]
160160
[[ "$output" = *"Hello World"* ]]
161161
[[ "$output" = *"runc-dmz: using /proc/self/exe clone"* ]]
@@ -231,14 +231,14 @@ function teardown() {
231231
grep -E '^boottime\s+1337\s+3141519$' <<<"$output"
232232
}
233233

234-
@test "runc run [exec error]" {
234+
@test "RUNC_DMZ=true runc run [exec error]" {
235235
cat <<EOF >rootfs/run.sh
236236
#!/mmnnttbb foo bar
237237
sh
238238
EOF
239239
chmod +x rootfs/run.sh
240240
update_config '.process.args = [ "/run.sh" ]'
241-
runc run test_hello
241+
RUNC_DMZ=true runc run test_hello
242242

243243
# Ensure that the output contains the right error message. For runc-dmz, both
244244
# nolibc and libc have the same formatting string (but libc will print the
@@ -248,14 +248,14 @@ EOF
248248
[[ "$output" = *"exec /run.sh: "* ]]
249249
}
250250

251-
@test "RUNC_DMZ=legacy runc run [execve error]" {
251+
@test "runc run [execve error]" {
252252
cat <<EOF >rootfs/run.sh
253253
#!/mmnnttbb foo bar
254254
sh
255255
EOF
256256
chmod +x rootfs/run.sh
257257
update_config '.process.args = [ "/run.sh" ]'
258-
RUNC_DMZ=legacy runc run test_hello
258+
runc run test_hello
259259
[ "$status" -ne 0 ]
260260

261261
# After the sync socket closed, we should not send error to parent

tests/integration/selinux.bats

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,14 @@ function teardown() {
3939
}
4040

4141
# https://github.com/opencontainers/runc/issues/4057
42-
@test "runc run (custom selinux label)" {
42+
@test "runc run (custom selinux label, RUNC_DMZ=true)" {
4343
update_config ' .process.selinuxLabel |= "system_u:system_r:container_t:s0:c4,c5"
4444
| .process.args = ["/bin/true"]'
45-
runc run tst
45+
RUNC_DMZ=true runc run tst
4646
[ "$status" -eq 0 ]
4747
}
4848

49-
@test "runc run (custom selinux label, RUNC_DMZ=legacy)" {
50-
export RUNC_DMZ=legacy
49+
@test "runc run (custom selinux label)" {
5150
update_config ' .process.selinuxLabel |= "system_u:system_r:container_t:s0:c4,c5"
5251
| .process.args = ["/bin/true"]'
5352
runc run tst

0 commit comments

Comments
 (0)