Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+35 -1
+3
include/linux/key-type.h
··· 74 74 */ 75 75 size_t def_datalen; 76 76 77 + unsigned int flags; 78 + #define KEY_TYPE_NET_DOMAIN 0x00000001 /* Keys of this type have a net namespace domain */ 79 + 77 80 /* vet a description */ 78 81 int (*vet_description)(const char *description); 79 82
+3
include/net/net_namespace.h
··· 71 71 */ 72 72 struct llist_node cleanup_list; /* namespaces on death row */ 73 73 74 + #ifdef CONFIG_KEYS 75 + struct key_tag *key_domain; /* Key domain of operation tag */ 76 + #endif 74 77 struct user_namespace *user_ns; /* Owning user namespace */ 75 78 struct ucounts *ucounts; 76 79 spinlock_t nsid_lock;
+20
net/core/net_namespace.c
··· 38 38 DECLARE_RWSEM(net_rwsem); 39 39 EXPORT_SYMBOL_GPL(net_rwsem); 40 40 41 + #ifdef CONFIG_KEYS 42 + static struct key_tag init_net_key_domain = { .usage = REFCOUNT_INIT(1) }; 43 + #endif 44 + 41 45 struct net init_net = { 42 46 .count = REFCOUNT_INIT(1), 43 47 .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head), 48 + #ifdef CONFIG_KEYS 49 + .key_domain = &init_net_key_domain, 50 + #endif 44 51 }; 45 52 EXPORT_SYMBOL(init_net); 46 53 ··· 393 386 if (!net) 394 387 goto out_free; 395 388 389 + #ifdef CONFIG_KEYS 390 + net->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL); 391 + if (!net->key_domain) 392 + goto out_free_2; 393 + refcount_set(&net->key_domain->usage, 1); 394 + #endif 395 + 396 396 rcu_assign_pointer(net->gen, ng); 397 397 out: 398 398 return net; 399 399 400 + #ifdef CONFIG_KEYS 401 + out_free_2: 402 + kmem_cache_free(net_cachep, net); 403 + net = NULL; 404 + #endif 400 405 out_free: 401 406 kfree(ng); 402 407 goto out; ··· 585 566 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { 586 567 list_del_init(&net->exit_list); 587 568 dec_net_namespaces(net->ucounts); 569 + key_remove_domain(net->key_domain); 588 570 put_user_ns(net->user_ns); 589 571 net_drop_ns(net); 590 572 }
+1
net/dns_resolver/dns_key.c
··· 314 314 315 315 struct key_type key_type_dns_resolver = { 316 316 .name = "dns_resolver", 317 + .flags = KEY_TYPE_NET_DOMAIN, 317 318 .preparse = dns_resolver_preparse, 318 319 .free_preparse = dns_resolver_free_preparse, 319 320 .instantiate = generic_key_instantiate,
+2
net/rxrpc/key.c
··· 43 43 */ 44 44 struct key_type key_type_rxrpc = { 45 45 .name = "rxrpc", 46 + .flags = KEY_TYPE_NET_DOMAIN, 46 47 .preparse = rxrpc_preparse, 47 48 .free_preparse = rxrpc_free_preparse, 48 49 .instantiate = generic_key_instantiate, ··· 59 58 */ 60 59 struct key_type key_type_rxrpc_s = { 61 60 .name = "rxrpc_s", 61 + .flags = KEY_TYPE_NET_DOMAIN, 62 62 .vet_description = rxrpc_vet_description_s, 63 63 .preparse = rxrpc_preparse_s, 64 64 .free_preparse = rxrpc_free_preparse_s,
+6 -1
security/keys/keyring.c
··· 17 17 #include <linux/seq_file.h> 18 18 #include <linux/err.h> 19 19 #include <linux/user_namespace.h> 20 + #include <linux/nsproxy.h> 20 21 #include <keys/keyring-type.h> 21 22 #include <keys/user-type.h> 22 23 #include <linux/assoc_array_priv.h> 23 24 #include <linux/uaccess.h> 25 + #include <net/net_namespace.h> 24 26 #include "internal.h" 25 27 26 28 /* ··· 222 220 223 221 memcpy(index_key->desc, index_key->description, n); 224 222 225 - index_key->domain_tag = &default_domain_tag; 223 + if (index_key->type->flags & KEY_TYPE_NET_DOMAIN) 224 + index_key->domain_tag = current->nsproxy->net_ns->key_domain; 225 + else 226 + index_key->domain_tag = &default_domain_tag; 226 227 hash_key_type_and_desc(index_key); 227 228 } 228 229