keys: Network namespace domain tag
Create key domain tags for network namespaces and make it possible to automatically tag keys that are used by networked services (e.g. AF_RXRPC, AFS, DNS) with the default network namespace if not set by the caller. This allows keys with the same description but in different namespaces to coexist within a keyring. Signed-off-by: David Howells <dhowells@redhat.com> cc: netdev@vger.kernel.org cc: linux-nfs@vger.kernel.org cc: linux-cifs@vger.kernel.org cc: linux-afs@lists.infradead.org
This commit is contained in:
parent
218e6424e7
commit
9b24261051
|
@ -74,6 +74,9 @@ struct key_type {
|
|||
*/
|
||||
size_t def_datalen;
|
||||
|
||||
unsigned int flags;
|
||||
#define KEY_TYPE_NET_DOMAIN 0x00000001 /* Keys of this type have a net namespace domain */
|
||||
|
||||
/* vet a description */
|
||||
int (*vet_description)(const char *description);
|
||||
|
||||
|
|
|
@ -71,6 +71,9 @@ struct net {
|
|||
*/
|
||||
struct llist_node cleanup_list; /* namespaces on death row */
|
||||
|
||||
#ifdef CONFIG_KEYS
|
||||
struct key_tag *key_domain; /* Key domain of operation tag */
|
||||
#endif
|
||||
struct user_namespace *user_ns; /* Owning user namespace */
|
||||
struct ucounts *ucounts;
|
||||
spinlock_t nsid_lock;
|
||||
|
|
|
@ -38,9 +38,16 @@ EXPORT_SYMBOL_GPL(net_namespace_list);
|
|||
DECLARE_RWSEM(net_rwsem);
|
||||
EXPORT_SYMBOL_GPL(net_rwsem);
|
||||
|
||||
#ifdef CONFIG_KEYS
|
||||
static struct key_tag init_net_key_domain = { .usage = REFCOUNT_INIT(1) };
|
||||
#endif
|
||||
|
||||
struct net init_net = {
|
||||
.count = REFCOUNT_INIT(1),
|
||||
.dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head),
|
||||
#ifdef CONFIG_KEYS
|
||||
.key_domain = &init_net_key_domain,
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL(init_net);
|
||||
|
||||
|
@ -386,10 +393,22 @@ static struct net *net_alloc(void)
|
|||
if (!net)
|
||||
goto out_free;
|
||||
|
||||
#ifdef CONFIG_KEYS
|
||||
net->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL);
|
||||
if (!net->key_domain)
|
||||
goto out_free_2;
|
||||
refcount_set(&net->key_domain->usage, 1);
|
||||
#endif
|
||||
|
||||
rcu_assign_pointer(net->gen, ng);
|
||||
out:
|
||||
return net;
|
||||
|
||||
#ifdef CONFIG_KEYS
|
||||
out_free_2:
|
||||
kmem_cache_free(net_cachep, net);
|
||||
net = NULL;
|
||||
#endif
|
||||
out_free:
|
||||
kfree(ng);
|
||||
goto out;
|
||||
|
@ -566,6 +585,7 @@ static void cleanup_net(struct work_struct *work)
|
|||
list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
|
||||
list_del_init(&net->exit_list);
|
||||
dec_net_namespaces(net->ucounts);
|
||||
key_remove_domain(net->key_domain);
|
||||
put_user_ns(net->user_ns);
|
||||
net_drop_ns(net);
|
||||
}
|
||||
|
|
|
@ -314,6 +314,7 @@ static long dns_resolver_read(const struct key *key,
|
|||
|
||||
struct key_type key_type_dns_resolver = {
|
||||
.name = "dns_resolver",
|
||||
.flags = KEY_TYPE_NET_DOMAIN,
|
||||
.preparse = dns_resolver_preparse,
|
||||
.free_preparse = dns_resolver_free_preparse,
|
||||
.instantiate = generic_key_instantiate,
|
||||
|
|
|
@ -43,6 +43,7 @@ static long rxrpc_read(const struct key *, char __user *, size_t);
|
|||
*/
|
||||
struct key_type key_type_rxrpc = {
|
||||
.name = "rxrpc",
|
||||
.flags = KEY_TYPE_NET_DOMAIN,
|
||||
.preparse = rxrpc_preparse,
|
||||
.free_preparse = rxrpc_free_preparse,
|
||||
.instantiate = generic_key_instantiate,
|
||||
|
@ -58,6 +59,7 @@ EXPORT_SYMBOL(key_type_rxrpc);
|
|||
*/
|
||||
struct key_type key_type_rxrpc_s = {
|
||||
.name = "rxrpc_s",
|
||||
.flags = KEY_TYPE_NET_DOMAIN,
|
||||
.vet_description = rxrpc_vet_description_s,
|
||||
.preparse = rxrpc_preparse_s,
|
||||
.free_preparse = rxrpc_free_preparse_s,
|
||||
|
|
|
@ -17,10 +17,12 @@
|
|||
#include <linux/seq_file.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/user_namespace.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#include <keys/keyring-type.h>
|
||||
#include <keys/user-type.h>
|
||||
#include <linux/assoc_array_priv.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
|
@ -220,7 +222,10 @@ void key_set_index_key(struct keyring_index_key *index_key)
|
|||
|
||||
memcpy(index_key->desc, index_key->description, n);
|
||||
|
||||
index_key->domain_tag = &default_domain_tag;
|
||||
if (index_key->type->flags & KEY_TYPE_NET_DOMAIN)
|
||||
index_key->domain_tag = current->nsproxy->net_ns->key_domain;
|
||||
else
|
||||
index_key->domain_tag = &default_domain_tag;
|
||||
hash_key_type_and_desc(index_key);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue