Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b242610 authored by David Howells's avatar David Howells
Browse files

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: default avatarDavid 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
parent 218e6424
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);

+3 −0
Original line number Diff line number Diff line
@@ -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;
+20 −0
Original line number Diff line number Diff line
@@ -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);
	}
+1 −0
Original line number Diff line number Diff line
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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,
Loading