From 8e5430c4bd9d39a5e405794f9c883f48de5205d9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 21 Sep 2017 14:02:31 +0200 Subject: [PATCH] nspawn: set up a new session keyring for the container process keyring material should not leak into the container. So far we relied on seccomp to deny access to the keyring, but given that we now made the seccomp configurable, and access to keyctl() and friends may optionally be permitted to containers now let's make sure we disconnect the callers keyring from the keyring of PID 1 in the container. --- src/nspawn/nspawn.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index cf804ed1b3..5ba09a994a 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1616,6 +1616,27 @@ static int setup_dev_console(const char *dest, const char *console) { return mount_verbose(LOG_ERR, console, to, NULL, MS_BIND, NULL); } +static int setup_keyring(void) { + key_serial_t keyring; + + /* Allocate a new session keyring for the container. This makes sure the keyring of the session systemd-nspawn + * was invoked from doesn't leak into the container. Note that by default we block keyctl() and request_key() + * anyway via seccomp so doing this operation isn't strictly necessary, but in case people explicitly whitelist + * these system calls let's make sure we don't leak anything into the container. */ + + keyring = keyctl(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0); + if (keyring == -1) { + if (errno == ENOSYS) + log_debug_errno(errno, "Kernel keyring not supported, ignoring."); + else if (IN_SET(errno, EACCES, EPERM)) + log_debug_errno(errno, "Kernel keyring access prohibited, ignoring."); + else + return log_error_errno(errno, "Setting up kernel keyring failed: %m"); + } + + return 0; +} + static int setup_kmsg(const char *dest, int kmsg_socket) { const char *from, *to; _cleanup_umask_ mode_t u; @@ -2642,6 +2663,10 @@ static int outer_child( if (r < 0) return r; + r = setup_keyring(); + if (r < 0) + return r; + r = setup_seccomp(arg_caps_retain, arg_syscall_whitelist, arg_syscall_blacklist); if (r < 0) return r;