Re: [RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator
On Thu, 2015-04-02 at 13:58 +0100, David Howells wrote: > Ian Kent wrote: > > > + > > + /* Namespace token */ > > + int umh_token; > > If you could put it after data_len so that all the smaller-than-wordsize > fields are together for better packing. OK. > > > + umh_wq_put_token(key->umh_token); > > Does gc.c need an extra #include for this? Umm ... you'd think so, wonder how it compiled without kmod.h > > > + /* If running within a container use the container namespace */ > > + if (current->nsproxy->net_ns != _net) > > + key->umh_token = umh_wq_get_token(0, "keys"); > > So keys live in the networking namespace? Perhaps checking the pid namespace would make more sense? > > > - 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); > > call_usermodehelper_keys_service() would appear to be superfluous. If > key->umh_token is 0, you call call_usermodehelper_keys() which then calls > call_usermodehelper_keys_service() with a 0 token... Yeah, not really worth the additional function. IIRC there are no other callers of call_usermodehelper_keys(). > > David -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator
On Thu, 2015-04-02 at 13:58 +0100, David Howells wrote: Ian Kent ra...@themaw.net wrote: + + /* Namespace token */ + int umh_token; If you could put it after data_len so that all the smaller-than-wordsize fields are together for better packing. OK. + umh_wq_put_token(key-umh_token); Does gc.c need an extra #include for this? Umm ... you'd think so, wonder how it compiled without kmod.h + /* 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); So keys live in the networking namespace? Perhaps checking the pid namespace would make more sense? - 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); call_usermodehelper_keys_service() would appear to be superfluous. If key-umh_token is 0, you call call_usermodehelper_keys() which then calls call_usermodehelper_keys_service() with a 0 token... Yeah, not really worth the additional function. IIRC there are no other callers of call_usermodehelper_keys(). David -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator
Ian Kent wrote: > + > + /* Namespace token */ > + int umh_token; If you could put it after data_len so that all the smaller-than-wordsize fields are together for better packing. > + umh_wq_put_token(key->umh_token); Does gc.c need an extra #include for this? > + /* If running within a container use the container namespace */ > + if (current->nsproxy->net_ns != _net) > + key->umh_token = umh_wq_get_token(0, "keys"); So keys live in the networking namespace? > - 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); call_usermodehelper_keys_service() would appear to be superfluous. If key->umh_token is 0, you call call_usermodehelper_keys() which then calls call_usermodehelper_keys_service() with a 0 token... David -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator
Ian Kent ra...@themaw.net wrote: + + /* Namespace token */ + int umh_token; If you could put it after data_len so that all the smaller-than-wordsize fields are together for better packing. + umh_wq_put_token(key-umh_token); Does gc.c need an extra #include for this? + /* 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); So keys live in the networking namespace? - 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); call_usermodehelper_keys_service() would appear to be superfluous. If key-umh_token is 0, you call call_usermodehelper_keys() which then calls call_usermodehelper_keys_service() with a 0 token... David -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator
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(>nkeys); key_alloc_serial(key); + /* If running within a container use the container namespace */ + if (current->nsproxy->net_ns != _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 */ -- To unsubscribe from this list: send the line
[RFC PATCH 5 7/7] KEYS: exec request key within service thread of key creator
From: Ian Kent ik...@redhat.com 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 ik...@redhat.com Cc: Benjamin Coddington bcodd...@redhat.com Cc: Al Viro v...@zeniv.linux.org.uk Cc: J. Bruce Fields bfie...@fieldses.org Cc: David Howells dhowe...@redhat.com Cc: Trond Myklebust trond.mykleb...@primarydata.com Cc: Oleg Nesterov onest...@redhat.com Cc: Eric W. Biederman ebied...@xmission.com Cc: Jeff Layton jeff.lay...@primarydata.com --- 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 linux/workqueue.h #include linux/random.h #include linux/err.h +#include net/net_namespace.h +#include linux/nsproxy.h #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 op key uid gid keyring keyring keyring */ @@ -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); +