mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 6 changed files with 35 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -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 a new issue