Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161739AbbBECem (ORCPT ); Wed, 4 Feb 2015 21:34:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39834 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756332AbbBECej (ORCPT ); Wed, 4 Feb 2015 21:34:39 -0500 Subject: [RFC PATCH 5/8] KEYS: exec request-key within the requesting task's init namespace 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: Thu, 05 Feb 2015 10:34:24 +0800 Message-ID: <20150205023423.8382.69433.stgit@pluto.fritz.box> In-Reply-To: <20150205021553.8382.16297.stgit@pluto.fritz.box> References: <20150205021553.8382.16297.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 Content-Length: 4366 Lines: 146 Containerized request key helper callbacks need the ability to execute a binary in a container's context. To do this calling an in kernel equivalent of setns(2) should be sufficient since the user mode helper execution kernel thread ultimately calls do_execve(). 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 --- security/keys/request_key.c | 60 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 9e79bbf..59282aa 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include #include "internal.h" #define key_negative_timeout 60 /* default timeout on a negative key's existence */ @@ -46,6 +49,11 @@ void complete_request_key(struct key_construction *cons, int error) } EXPORT_SYMBOL(complete_request_key); +struct request_key_info { + struct key *keyring; + struct task_struct *tsk; +}; + /* * Initialise a usermode helper that is going to have a specific session * keyring. @@ -55,9 +63,18 @@ EXPORT_SYMBOL(complete_request_key); */ static int umh_keys_init(struct subprocess_info *info, struct cred *cred) { - struct key *keyring = info->data; + struct request_key_info *rki = info->data; + struct task_struct *tsk = rki->tsk; + + if (tsk) { + int err; + + err = umh_enter_ns(tsk, cred); + if (err) + return err; + } - return install_session_keyring_to_cred(cred, keyring); + return install_session_keyring_to_cred(cred, rki->keyring); } /* @@ -65,8 +82,11 @@ static int umh_keys_init(struct subprocess_info *info, struct cred *cred) */ static void umh_keys_cleanup(struct subprocess_info *info) { - struct key *keyring = info->data; - key_put(keyring); + struct request_key_info *rki = info->data; + if (rki->tsk) + put_task_struct(rki->tsk); + key_put(rki->keyring); + kfree(rki); } /* @@ -76,12 +96,32 @@ static int call_usermodehelper_keys(char *path, char **argv, char **envp, struct key *session_keyring, int flags) { struct subprocess_info *info; + struct request_key_info *rki; + unsigned int use_ns = flags & UMH_USE_NS; + struct task_struct *tsk = NULL; + + rki = kmalloc(sizeof(*rki), GFP_KERNEL); + if (!rki) + return -ENOMEM; + + if (use_ns) { + tsk = umh_get_init_pid(); + if (IS_ERR(tsk)) + return PTR_ERR(tsk); + } + + rki->keyring = session_keyring; + rki->tsk = tsk; info = call_usermodehelper_setup(path, argv, envp, GFP_KERNEL, umh_keys_init, umh_keys_cleanup, - session_keyring); - if (!info) + rki); + if (!info) { + if (tsk) + put_task_struct(rki->tsk); + kfree(rki); return -ENOMEM; + } key_get(session_keyring); return call_usermodehelper_exec(info, flags); @@ -102,10 +142,15 @@ static int call_sbin_request_key(struct key_construction *cons, char *argv[9], *envp[3], uid_str[12], gid_str[12]; char key_str[12], keyring_str[3][12]; char desc[20]; + int flags = UMH_WAIT_PROC; int ret, i; kenter("{%d},{%d},%s", key->serial, authkey->serial, op); + /* If running within a container use the container namespace */ + if (current->nsproxy->net_ns != &init_net) + flags |= UMH_USE_NS; + ret = install_user_keyrings(); if (ret < 0) goto error_alloc; @@ -172,8 +217,7 @@ 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); + ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, flags); kdebug("usermode -> 0x%x", ret); if (ret >= 0) { /* ret is the exit/wait code */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/