mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-10 21:53:57 +08:00
dac4171746
The idea is to remove the need for cloning the entire runc binary by replacing the final execve() call of the container process with an execve() call to a clone of a small C binary which just does an execve() of its arguments. This provides similar protection against CVE-2019-5736 but without requiring a >10MB binary copy for each "runc init". When compiled with musl, runc-dmz is 13kB (though unfortunately with glibc, it is 1.1MB which is still quite large). It should be noted that there is still a window where the container processes could get access to the host runc binary, but because we set ourselves as non-dumpable the container would need CAP_SYS_PTRACE (which is not enabled by default in Docker) in order to get around the proc_fd_access_allowed() checks. In addition, since Linux 4.10[1] the kernel blocks access entirely for user namespaced containers in this scenario. For those cases we cannot use runc-dmz, but most containers won't have this issue. This new runc-dmz binary can be opted out of at compile time by setting the "runc_nodmz" buildtag, and at runtime by setting the RUNC_DMZ=legacy environment variable. In both cases, runc will fall back to the classic /proc/self/exe-based cloning trick. If /proc/self/exe is already a sealed memfd (namely if the user is using contrib/cmd/memfd-bind to create a persistent sealed memfd for runc), neither runc-dmz nor /proc/self/exe cloning will be used because they are not necessary. [1]: https://github.com/torvalds/linux/commit/bfedb589252c01fa505ac9f6f2a3d5d68d707ef4 Co-authored-by: lifubang <lifubang@acmcoder.com> Signed-off-by: lifubang <lifubang@acmcoder.com> [cyphar: address various review nits] [cyphar: fix runc-dmz cross-compilation] [cyphar: embed runc-dmz into runc binary and clone in Go code] [cyphar: make runc-dmz optional, with fallback to /proc/self/exe cloning] [cyphar: do not use runc-dmz when the container has certain privs] Co-authored-by: Aleksa Sarai <cyphar@cyphar.com> Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
62 lines
1.6 KiB
Makefile
62 lines
1.6 KiB
Makefile
# NOTE: Make sure you keep this file in sync with scripts/lib.sh.
|
|
|
|
GO ?= go
|
|
GOARCH ?= $(shell $(GO) env GOARCH)
|
|
|
|
ifneq ($(shell grep -i "ID_LIKE=.*suse" /etc/os-release),)
|
|
# openSUSE has a custom PLATFORM
|
|
PLATFORM ?= suse-linux
|
|
IS_SUSE := 1
|
|
else
|
|
PLATFORM ?= linux-gnu
|
|
endif
|
|
|
|
ifeq ($(GOARCH),$(shell GOARCH= $(GO) env GOARCH))
|
|
# use the native CC and STRIP
|
|
HOST :=
|
|
else ifeq ($(GOARCH),386)
|
|
# Always use the 64-bit compiler to build the 386 binary, which works for
|
|
# the more common cross-build method for x86 (namely, the equivalent of
|
|
# dpkg --add-architecture).
|
|
ifdef IS_SUSE
|
|
# There is no x86_64-suse-linux-gcc, so use the native one.
|
|
HOST :=
|
|
CPU_TYPE := i586
|
|
else
|
|
HOST := x86_64-$(PLATFORM)-
|
|
CPU_TYPE := i686
|
|
endif
|
|
CFLAGS := -m32 -march=$(CPU_TYPE) $(CFLAGS)
|
|
else ifeq ($(GOARCH),amd64)
|
|
ifdef IS_SUSE
|
|
# There is no x86_64-suse-linux-gcc, so use the native one.
|
|
HOST :=
|
|
else
|
|
HOST := x86_64-$(PLATFORM)-
|
|
endif
|
|
else ifeq ($(GOARCH),arm64)
|
|
HOST := aarch64-$(PLATFORM)-
|
|
else ifeq ($(GOARCH),arm)
|
|
# HOST already configured by release_build.sh in this case.
|
|
else ifeq ($(GOARCH),armel)
|
|
HOST := arm-$(PLATFORM)eabi-
|
|
else ifeq ($(GOARCH),armhf)
|
|
HOST := arm-$(PLATFORM)eabihf-
|
|
else ifeq ($(GOARCH),ppc64le)
|
|
HOST := powerpc64le-$(PLATFORM)-
|
|
else ifeq ($(GOARCH),riscv64)
|
|
HOST := riscv64-$(PLATFORM)-
|
|
else ifeq ($(GOARCH),s390x)
|
|
HOST := s390x-$(PLATFORM)-
|
|
else
|
|
$(error Unsupported GOARCH $(GOARCH))
|
|
endif
|
|
|
|
ifeq ($(origin CC),$(filter $(origin CC),undefined default))
|
|
# Override CC if it's undefined or just the default value set by Make.
|
|
CC := $(HOST)gcc
|
|
export CC
|
|
endif
|
|
STRIP ?= $(HOST)strip
|
|
export STRIP
|