From a4e0a594b1b6f5cf24389cd3f5cb1bae0999bbaf Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Thu, 8 Jun 2017 09:00:48 -0600 Subject: [PATCH] add a static usermode helper The binary is used in tandem with CONFIG_STATIC_USERMODEHELPER=y in 4.11+, see the big comment in the binary for the current whitelist of binaries. Signed-off-by: Tycho Andersen --- kernel/kernel_config-4.11.x | 3 +- pkg/init/Dockerfile | 7 +++++ pkg/init/Makefile | 2 +- pkg/init/usermode-helper.c | 55 +++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 pkg/init/usermode-helper.c diff --git a/kernel/kernel_config-4.11.x b/kernel/kernel_config-4.11.x index f786cd3b9..7e9c76a9c 100644 --- a/kernel/kernel_config-4.11.x +++ b/kernel/kernel_config-4.11.x @@ -3560,7 +3560,8 @@ CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY=y # CONFIG_HARDENED_USERCOPY_PAGESPAN is not set -# CONFIG_STATIC_USERMODEHELPER is not set +CONFIG_STATIC_USERMODEHELPER=y +CONFIG_STATIC_USERMODEHELPER_PATH="/sbin/usermode-helper" # CONFIG_SECURITY_SELINUX is not set # CONFIG_SECURITY_SMACK is not set # CONFIG_SECURITY_TOMOYO is not set diff --git a/pkg/init/Dockerfile b/pkg/init/Dockerfile index 850066d8e..85af575cb 100644 --- a/pkg/init/Dockerfile +++ b/pkg/init/Dockerfile @@ -1,3 +1,9 @@ +FROM linuxkit/alpine:630ee558e4869672fae230c78364e367b8ea67a9 AS build +RUN apk add --no-cache --initdb alpine-baselayout make gcc musl-dev + +ADD usermode-helper.c . +RUN make usermode-helper + FROM linuxkit/alpine:630ee558e4869672fae230c78364e367b8ea67a9 AS mirror RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/ RUN apk add --no-cache --initdb -p /out alpine-baselayout busybox musl @@ -9,6 +15,7 @@ FROM scratch ENTRYPOINT [] CMD [] WORKDIR / +COPY --from=build usermode-helper /sbin/ COPY --from=mirror /out/ / COPY init / COPY etc etc/ diff --git a/pkg/init/Makefile b/pkg/init/Makefile index 4b5eaf067..058c4487a 100644 --- a/pkg/init/Makefile +++ b/pkg/init/Makefile @@ -3,7 +3,7 @@ default: push ORG?=linuxkit IMAGE=init -DEPS=Dockerfile init $(wildcard etc/*) $(wildcard etc/init.d/*) +DEPS=Dockerfile init $(wildcard etc/*) $(wildcard etc/init.d/*) usermode-helper.c HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}') diff --git a/pkg/init/usermode-helper.c b/pkg/init/usermode-helper.c new file mode 100644 index 000000000..556410669 --- /dev/null +++ b/pkg/init/usermode-helper.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int i; + + /* TODO: this doesn't go anywhere useful right now. It would be nice to + * switch this to syslog() (or some other mechanism) so that we can + * actually read the contents. + */ + fprintf(stderr, "usermodehelper: "); + for (i = 0; i < argc; i++) { + fprintf(stderr, "%s ", argv[i]); + } + fprintf(stderr, "\n"); + + if (!strcmp(argv[0], "/sbin/mdev")) { + /* busybox uses /sbin/mdev for early uevent bootstrapping */ + execv(argv[0], argv); + } else if (!strcmp(argv[0], "/sbin/modprobe")) { + /* allow modprobe */ + execv(argv[0], argv); + } else if (!strcmp(argv[0], "/sbin/poweroff") || + !strcmp(argv[0], "/sbin/reboot")) { + /* poweroff and reboot are allowed */ + execv(argv[0], argv); + } else { + /* This means either we got an unexpected call from the kernel + * or someone is doing something nefarious. Some other possible + * expected callers are: + * - for core dumps. we don't have a "core" binary, and don't + * set this by default to anything. when we do, we need to + * whitelist it here + * - /linuxrc: we're not doing legacy root setup, so we don't + * need this + * - a few drivers and filesystems (drbd, nfs, nfsd, ocfs2) + * - cgroup notify_on_release handlers, which we do not set + * (but e.g. systemd needs, if anyone ever tries to boot + * that on linuxkit) + * - /sbin/request-key, which we don't provide + * - on x86, machine check + * + * Today we only call mdev and modprobe, but as we add more + * features to linuxkit this whitelist may need changing (or a + * policy, like always allow stuff in /sbin). + */ + exit(2); + } + + perror("exec failed"); + return 1; +}