Skip to content

Commit

Permalink
keys: Network namespace domain tag
Browse files Browse the repository at this point in the history
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 <[email protected]>
cc: [email protected]
cc: [email protected]
cc: [email protected]
cc: [email protected]
  • Loading branch information
dhowells committed Jun 26, 2019
1 parent 218e642 commit 9b24261
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 1 deletion.
3 changes: 3 additions & 0 deletions include/linux/key-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions include/net/net_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions net/core/net_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions net/dns_resolver/dns_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions net/rxrpc/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion security/keys/keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

/*
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit 9b24261

Please sign in to comment.