From: Benjamin Coddington <[email protected]> Copy the current task's namespaces into the request-key userspace helper to restrict contained processes from executing key instantiation processes outside their containers.
Signed-off-by: Benjamin Coddington <[email protected]> Signed-off-by: Ian Kent <[email protected]> Cc: Al Viro <[email protected]> Cc: J. Bruce Fields <[email protected]> Cc: David Howells <[email protected]> Cc: Trond Myklebust <[email protected]> Cc: Stanislav Kinsbursky <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Eric W. Biederman <[email protected]> --- security/keys/request_key.c | 45 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/security/keys/request_key.c b/security/keys/request_key.c index bb4337c..b03feec 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -17,6 +17,8 @@ #include <linux/err.h> #include <linux/keyctl.h> #include <linux/slab.h> +#include <linux/nsproxy.h> +#include <linux/mount.h> #include "internal.h" #define key_negative_timeout 60 /* default timeout on a negative key's existence */ @@ -46,6 +48,11 @@ void complete_request_key(struct key_construction *cons, int error) } EXPORT_SYMBOL(complete_request_key); +struct request_key_info { + struct key *keyring; + struct nsproxy *nsproxy; +}; + /* * Initialise a usermode helper that is going to have a specific session * keyring. @@ -55,9 +62,14 @@ 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 nsproxy *ns = rki->nsproxy; - return install_session_keyring_to_cred(cred, keyring); + if (ns) { + mntns_setfs(ns->mnt_ns); + switch_task_namespaces(current, ns); + } + return install_session_keyring_to_cred(cred, rki->keyring); } /* @@ -65,8 +77,9 @@ 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; + key_put(rki->keyring); + kfree(rki); } /* @@ -76,12 +89,32 @@ static int call_usermodehelper_keys(char *path, char **argv, char **envp, struct key *session_keyring, int wait) { struct subprocess_info *info; + struct request_key_info *rki; + struct nsproxy *ns; + + ns = umh_open_ns(); + if (ns && IS_ERR(ns)) + return PTR_ERR(ns); + + rki = kmalloc(sizeof(*rki), GFP_KERNEL); + if (!rki) { + if (ns) + free_nsproxy(ns); + return -ENOMEM; + } + + rki->keyring = session_keyring; + rki->nsproxy = ns; info = call_usermodehelper_setup(path, argv, envp, GFP_KERNEL, umh_keys_init, umh_keys_cleanup, - session_keyring); - if (!info) + rki); + if (!info) { + if (ns) + free_nsproxy(ns); + kfree(rki); return -ENOMEM; + } key_get(session_keyring); return call_usermodehelper_exec(info, wait); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

