From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754534AbbCaDPx (ORCPT ); Mon, 30 Mar 2015 23:15:53 -0400 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:43231 "EHLO out2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754035AbbCaDPt (ORCPT ); Mon, 30 Mar 2015 23:15:49 -0400 X-Sasl-enc: iHMhvy9/skGIx/OJcnuhg4YQ1Do2uDXWVUSQINErfZAg 1427771748 Subject: [RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator From: Ian Kent To: Kernel Mailing List Cc: David Howells , Oleg Nesterov , Trond Myklebust , "J. Bruce Fields" , Benjamin Coddington , Al Viro , Jeff Layton , "Eric W. Biederman" Date: Tue, 31 Mar 2015 11:15:35 +0800 Message-ID: <20150331031533.10464.1615.stgit@pluto.fritz.box> In-Reply-To: <20150331030340.10464.30272.stgit@pluto.fritz.box> References: <20150331030340.10464.30272.stgit@pluto.fritz.box> User-Agent: StGit/0.17-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ian Kent Containerized request key helper callbacks need the ability to execute a binary in a container's context. To do that get a token to a service thread created within the container environment for usermode helper calls. Signed-off-by: Ian Kent Cc: Benjamin Coddington Cc: Al Viro Cc: J. Bruce Fields Cc: David Howells Cc: Trond Myklebust Cc: Oleg Nesterov Cc: Eric W. Biederman Cc: Jeff Layton --- include/linux/key.h | 3 +++ security/keys/gc.c | 2 ++ security/keys/key.c | 5 +++++ security/keys/request_key.c | 34 +++++++++++++++++++++++++++------- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/include/linux/key.h b/include/linux/key.h index e1d4715..144727d 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -209,6 +209,9 @@ struct key { } payload; struct assoc_array keys; }; + + /* Namespace token */ + int umh_token; }; extern struct key *key_alloc(struct key_type *type, diff --git a/security/keys/gc.c b/security/keys/gc.c index c795237..c689ffd 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -156,6 +156,8 @@ static noinline void key_gc_unused_keys(struct list_head *keys) kfree(key->description); + umh_wq_put_token(key->umh_token); + #ifdef KEY_DEBUGGING key->magic = KEY_DEBUG_MAGIC_X; #endif diff --git a/security/keys/key.c b/security/keys/key.c index aee2ec5..3ca0825 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "internal.h" struct kmem_cache *key_jar; @@ -309,6 +311,9 @@ struct key *key_alloc(struct key_type *type, const char *desc, /* publish the key by giving it a serial number */ atomic_inc(&user->nkeys); key_alloc_serial(key); + /* If running within a container use the container namespace */ + if (current->nsproxy->net_ns != &init_net) + key->umh_token = umh_wq_get_token(0, "keys"); error: return key; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index e865f9f..233e837 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -70,26 +70,40 @@ static void umh_keys_cleanup(struct subprocess_info *info) } /* - * Call a usermode helper with a specific session keyring. + * Call a usermode helper with a specific session keyring and execute + * within a namespace. */ -static int call_usermodehelper_keys(char *path, char **argv, char **envp, - struct key *session_keyring, int wait) +static int call_usermodehelper_keys_service(char *path, + char **argv, char **envp, + struct key *session_keyring, + int token, unsigned int wait) { struct subprocess_info *info; unsigned int gfp_mask = (wait & UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; info = call_usermodehelper_setup(path, argv, envp, gfp_mask, - umh_keys_init, umh_keys_cleanup, - session_keyring); + umh_keys_init, umh_keys_cleanup, + session_keyring); if (!info) return -ENOMEM; + info->wq_token = token; key_get(session_keyring); return call_usermodehelper_exec(info, wait); } /* + * Call a usermode helper with a specific session keyring. + */ +static int call_usermodehelper_keys(char *path, char **argv, char **envp, + struct key *session_keyring, int wait) +{ + return call_usermodehelper_keys_service(path, argv, envp, + session_keyring, 0, wait); +} + +/* * Request userspace finish the construction of a key * - execute "/sbin/request-key " */ @@ -174,8 +188,14 @@ static int call_sbin_request_key(struct key_construction *cons, argv[i] = NULL; /* do it */ - ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, - UMH_WAIT_PROC); + /* If running within a container use the container namespace */ + if (key->umh_token) + ret = call_usermodehelper_keys_service(argv[0], argv, envp, + keyring, key->umh_token, + UMH_WAIT_PROC); + else + ret = call_usermodehelper_keys(argv[0], argv, envp, + keyring, UMH_WAIT_PROC); kdebug("usermode -> 0x%x", ret); if (ret >= 0) { /* ret is the exit/wait code */