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;
 | 
						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 */
 | 
						/* vet a description */
 | 
				
			||||||
	int (*vet_description)(const char *description);
 | 
						int (*vet_description)(const char *description);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,9 @@ struct net {
 | 
				
			||||||
						 */
 | 
											 */
 | 
				
			||||||
	struct llist_node	cleanup_list;	/* namespaces on death row */
 | 
						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 user_namespace   *user_ns;	/* Owning user namespace */
 | 
				
			||||||
	struct ucounts		*ucounts;
 | 
						struct ucounts		*ucounts;
 | 
				
			||||||
	spinlock_t		nsid_lock;
 | 
						spinlock_t		nsid_lock;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,9 +38,16 @@ EXPORT_SYMBOL_GPL(net_namespace_list);
 | 
				
			||||||
DECLARE_RWSEM(net_rwsem);
 | 
					DECLARE_RWSEM(net_rwsem);
 | 
				
			||||||
EXPORT_SYMBOL_GPL(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 = {
 | 
					struct net init_net = {
 | 
				
			||||||
	.count		= REFCOUNT_INIT(1),
 | 
						.count		= REFCOUNT_INIT(1),
 | 
				
			||||||
	.dev_base_head	= LIST_HEAD_INIT(init_net.dev_base_head),
 | 
						.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);
 | 
					EXPORT_SYMBOL(init_net);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -386,10 +393,22 @@ static struct net *net_alloc(void)
 | 
				
			||||||
	if (!net)
 | 
						if (!net)
 | 
				
			||||||
		goto out_free;
 | 
							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);
 | 
						rcu_assign_pointer(net->gen, ng);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return net;
 | 
						return net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_KEYS
 | 
				
			||||||
 | 
					out_free_2:
 | 
				
			||||||
 | 
						kmem_cache_free(net_cachep, net);
 | 
				
			||||||
 | 
						net = NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
out_free:
 | 
					out_free:
 | 
				
			||||||
	kfree(ng);
 | 
						kfree(ng);
 | 
				
			||||||
	goto out;
 | 
						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_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
 | 
				
			||||||
		list_del_init(&net->exit_list);
 | 
							list_del_init(&net->exit_list);
 | 
				
			||||||
		dec_net_namespaces(net->ucounts);
 | 
							dec_net_namespaces(net->ucounts);
 | 
				
			||||||
 | 
							key_remove_domain(net->key_domain);
 | 
				
			||||||
		put_user_ns(net->user_ns);
 | 
							put_user_ns(net->user_ns);
 | 
				
			||||||
		net_drop_ns(net);
 | 
							net_drop_ns(net);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -314,6 +314,7 @@ static long dns_resolver_read(const struct key *key,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct key_type key_type_dns_resolver = {
 | 
					struct key_type key_type_dns_resolver = {
 | 
				
			||||||
	.name		= "dns_resolver",
 | 
						.name		= "dns_resolver",
 | 
				
			||||||
 | 
						.flags		= KEY_TYPE_NET_DOMAIN,
 | 
				
			||||||
	.preparse	= dns_resolver_preparse,
 | 
						.preparse	= dns_resolver_preparse,
 | 
				
			||||||
	.free_preparse	= dns_resolver_free_preparse,
 | 
						.free_preparse	= dns_resolver_free_preparse,
 | 
				
			||||||
	.instantiate	= generic_key_instantiate,
 | 
						.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 = {
 | 
					struct key_type key_type_rxrpc = {
 | 
				
			||||||
	.name		= "rxrpc",
 | 
						.name		= "rxrpc",
 | 
				
			||||||
 | 
						.flags		= KEY_TYPE_NET_DOMAIN,
 | 
				
			||||||
	.preparse	= rxrpc_preparse,
 | 
						.preparse	= rxrpc_preparse,
 | 
				
			||||||
	.free_preparse	= rxrpc_free_preparse,
 | 
						.free_preparse	= rxrpc_free_preparse,
 | 
				
			||||||
	.instantiate	= generic_key_instantiate,
 | 
						.instantiate	= generic_key_instantiate,
 | 
				
			||||||
| 
						 | 
					@ -58,6 +59,7 @@ EXPORT_SYMBOL(key_type_rxrpc);
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct key_type key_type_rxrpc_s = {
 | 
					struct key_type key_type_rxrpc_s = {
 | 
				
			||||||
	.name		= "rxrpc_s",
 | 
						.name		= "rxrpc_s",
 | 
				
			||||||
 | 
						.flags		= KEY_TYPE_NET_DOMAIN,
 | 
				
			||||||
	.vet_description = rxrpc_vet_description_s,
 | 
						.vet_description = rxrpc_vet_description_s,
 | 
				
			||||||
	.preparse	= rxrpc_preparse_s,
 | 
						.preparse	= rxrpc_preparse_s,
 | 
				
			||||||
	.free_preparse	= rxrpc_free_preparse_s,
 | 
						.free_preparse	= rxrpc_free_preparse_s,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,10 +17,12 @@
 | 
				
			||||||
#include <linux/seq_file.h>
 | 
					#include <linux/seq_file.h>
 | 
				
			||||||
#include <linux/err.h>
 | 
					#include <linux/err.h>
 | 
				
			||||||
#include <linux/user_namespace.h>
 | 
					#include <linux/user_namespace.h>
 | 
				
			||||||
 | 
					#include <linux/nsproxy.h>
 | 
				
			||||||
#include <keys/keyring-type.h>
 | 
					#include <keys/keyring-type.h>
 | 
				
			||||||
#include <keys/user-type.h>
 | 
					#include <keys/user-type.h>
 | 
				
			||||||
#include <linux/assoc_array_priv.h>
 | 
					#include <linux/assoc_array_priv.h>
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
 | 
					#include <net/net_namespace.h>
 | 
				
			||||||
#include "internal.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);
 | 
						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);
 | 
						hash_key_type_and_desc(index_key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue