Commit a58946c1 authored by David Howells's avatar David Howells

keys: Pass the network namespace into request_key mechanism

Create a request_key_net() function and use it to pass the network
namespace domain tag into DNS revolver keys and rxrpc/AFS keys so that keys
for different domains can coexist in the same 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 9b242610
...@@ -1102,26 +1102,42 @@ payload contents" for more information. ...@@ -1102,26 +1102,42 @@ payload contents" for more information.
See also Documentation/security/keys/request-key.rst. See also Documentation/security/keys/request-key.rst.
* To search for a key in a specific domain, call:
struct key *request_key_tag(const struct key_type *type,
const char *description,
struct key_tag *domain_tag,
const char *callout_info);
This is identical to request_key(), except that a domain tag may be
specifies that causes search algorithm to only match keys matching that
tag. The domain_tag may be NULL, specifying a global domain that is
separate from any nominated domain.
* To search for a key, passing auxiliary data to the upcaller, call:: * To search for a key, passing auxiliary data to the upcaller, call::
struct key *request_key_with_auxdata(const struct key_type *type, struct key *request_key_with_auxdata(const struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const void *callout_info, const void *callout_info,
size_t callout_len, size_t callout_len,
void *aux); void *aux);
This is identical to request_key(), except that the auxiliary data is This is identical to request_key_tag(), except that the auxiliary data is
passed to the key_type->request_key() op if it exists, and the callout_info passed to the key_type->request_key() op if it exists, and the
is a blob of length callout_len, if given (the length may be 0). callout_info is a blob of length callout_len, if given (the length may be
0).
* To search for a key under RCU conditions, call:: * To search for a key under RCU conditions, call::
struct key *request_key_rcu(const struct key_type *type, struct key *request_key_rcu(const struct key_type *type,
const char *description); const char *description,
struct key_tag *domain_tag);
which is similar to request_key() except that it does not check for keys which is similar to request_key_tag() except that it does not check for
that are under construction and it will not call out to userspace to keys that are under construction and it will not call out to userspace to
construct a key if it can't find a match. construct a key if it can't find a match.
......
...@@ -13,10 +13,18 @@ The process starts by either the kernel requesting a service by calling ...@@ -13,10 +13,18 @@ The process starts by either the kernel requesting a service by calling
const char *description, const char *description,
const char *callout_info); const char *callout_info);
or::
struct key *request_key_tag(const struct key_type *type,
const char *description,
const struct key_tag *domain_tag,
const char *callout_info);
or:: or::
struct key *request_key_with_auxdata(const struct key_type *type, struct key *request_key_with_auxdata(const struct key_type *type,
const char *description, const char *description,
const struct key_tag *domain_tag,
const char *callout_info, const char *callout_info,
size_t callout_len, size_t callout_len,
void *aux); void *aux);
...@@ -24,7 +32,8 @@ or:: ...@@ -24,7 +32,8 @@ or::
or:: or::
struct key *request_key_rcu(const struct key_type *type, struct key *request_key_rcu(const struct key_type *type,
const char *description); const char *description,
const struct key_tag *domain_tag);
Or by userspace invoking the request_key system call:: Or by userspace invoking the request_key system call::
...@@ -38,14 +47,18 @@ does not need to link the key to a keyring to prevent it from being immediately ...@@ -38,14 +47,18 @@ does not need to link the key to a keyring to prevent it from being immediately
destroyed. The kernel interface returns a pointer directly to the key, and destroyed. The kernel interface returns a pointer directly to the key, and
it's up to the caller to destroy the key. it's up to the caller to destroy the key.
The request_key_with_auxdata() calls is like the in-kernel request_key() call, The request_key_tag() call is like the in-kernel request_key(), except that it
except that they permit auxiliary data to be passed to the upcaller (the also takes a domain tag that allows keys to be separated by namespace and
default is NULL). This is only useful for those key types that define their killed off as a group.
own upcall mechanism rather than using /sbin/request-key.
The request_key_with_auxdata() calls is like the request_key_tag() call, except
that they permit auxiliary data to be passed to the upcaller (the default is
NULL). This is only useful for those key types that define their own upcall
mechanism rather than using /sbin/request-key.
The request_key_rcu() call is like the in-kernel request_key() call, except The request_key_rcu() call is like the request_key_tag() call, except that it
that it doesn't check for keys that are under construction and doesn't attempt doesn't check for keys that are under construction and doesn't attempt to
to construct missing keys. construct missing keys.
The userspace interface links the key to a keyring associated with the process The userspace interface links the key to a keyring associated with the process
to prevent the key from going away, and returns the serial number of the key to to prevent the key from going away, and returns the serial number of the key to
......
...@@ -250,8 +250,8 @@ struct afs_vlserver_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry ...@@ -250,8 +250,8 @@ struct afs_vlserver_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry
_enter("%s", cell->name); _enter("%s", cell->name);
ret = dns_query("afsdb", cell->name, cell->name_len, "srv=1", ret = dns_query(cell->net->net, "afsdb", cell->name, cell->name_len,
&result, _expiry, true); "srv=1", &result, _expiry, true);
if (ret < 0) { if (ret < 0) {
_leave(" = %d [dns]", ret); _leave(" = %d [dns]", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -28,6 +28,7 @@ const struct file_operations afs_dynroot_file_operations = { ...@@ -28,6 +28,7 @@ const struct file_operations afs_dynroot_file_operations = {
static int afs_probe_cell_name(struct dentry *dentry) static int afs_probe_cell_name(struct dentry *dentry)
{ {
struct afs_cell *cell; struct afs_cell *cell;
struct afs_net *net = afs_d2net(dentry);
const char *name = dentry->d_name.name; const char *name = dentry->d_name.name;
size_t len = dentry->d_name.len; size_t len = dentry->d_name.len;
int ret; int ret;
...@@ -40,13 +41,14 @@ static int afs_probe_cell_name(struct dentry *dentry) ...@@ -40,13 +41,14 @@ static int afs_probe_cell_name(struct dentry *dentry)
len--; len--;
} }
cell = afs_lookup_cell_rcu(afs_d2net(dentry), name, len); cell = afs_lookup_cell_rcu(net, name, len);
if (!IS_ERR(cell)) { if (!IS_ERR(cell)) {
afs_put_cell(afs_d2net(dentry), cell); afs_put_cell(net, cell);
return 0; return 0;
} }
ret = dns_query("afsdb", name, len, "srv=1", NULL, NULL, false); ret = dns_query(net->net, "afsdb", name, len, "srv=1",
NULL, NULL, false);
if (ret == -ENODATA) if (ret == -ENODATA)
ret = -EDESTADDRREQ; ret = -EDESTADDRREQ;
return ret; return ret;
......
...@@ -77,7 +77,8 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -77,7 +77,8 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
goto name_is_IP_address; goto name_is_IP_address;
/* Perform the upcall */ /* Perform the upcall */
rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL, false); rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len,
NULL, ip_addr, NULL, false);
if (rc < 0) if (rc < 0)
cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n", cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
__func__, len, len, hostname); __func__, len, len, hostname);
......
...@@ -22,7 +22,8 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen, ...@@ -22,7 +22,8 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
char *ip_addr = NULL; char *ip_addr = NULL;
int ip_len; int ip_len;
ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL, false); ip_len = dns_query(net, NULL, name, namelen, NULL, &ip_addr, NULL,
false);
if (ip_len > 0) if (ip_len > 0)
ret = rpc_pton(net, ip_addr, ip_len, sa, salen); ret = rpc_pton(net, ip_addr, ip_len, sa, salen);
else else
......
...@@ -291,7 +291,7 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen, ...@@ -291,7 +291,7 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen,
if (IS_ERR(rkey)) { if (IS_ERR(rkey)) {
mutex_lock(&idmap->idmap_mutex); mutex_lock(&idmap->idmap_mutex);
rkey = request_key_with_auxdata(&key_type_id_resolver_legacy, rkey = request_key_with_auxdata(&key_type_id_resolver_legacy,
desc, "", 0, idmap); desc, NULL, "", 0, idmap);
mutex_unlock(&idmap->idmap_mutex); mutex_unlock(&idmap->idmap_mutex);
} }
if (!IS_ERR(rkey)) if (!IS_ERR(rkey))
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
#include <uapi/linux/dns_resolver.h> #include <uapi/linux/dns_resolver.h>
extern int dns_query(const char *type, const char *name, size_t namelen, struct net;
extern int dns_query(struct net *net, const char *type, const char *name, size_t namelen,
const char *options, char **_result, time64_t *_expiry, const char *options, char **_result, time64_t *_expiry,
bool invalidate); bool invalidate);
......
...@@ -36,6 +36,7 @@ typedef int32_t key_serial_t; ...@@ -36,6 +36,7 @@ typedef int32_t key_serial_t;
typedef uint32_t key_perm_t; typedef uint32_t key_perm_t;
struct key; struct key;
struct net;
#ifdef CONFIG_KEYS #ifdef CONFIG_KEYS
...@@ -296,19 +297,57 @@ static inline void key_ref_put(key_ref_t key_ref) ...@@ -296,19 +297,57 @@ static inline void key_ref_put(key_ref_t key_ref)
key_put(key_ref_to_ptr(key_ref)); key_put(key_ref_to_ptr(key_ref));
} }
extern struct key *request_key(struct key_type *type, extern struct key *request_key_tag(struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const char *callout_info); const char *callout_info);
extern struct key *request_key_rcu(struct key_type *type, extern struct key *request_key_rcu(struct key_type *type,
const char *description); const char *description,
struct key_tag *domain_tag);
extern struct key *request_key_with_auxdata(struct key_type *type, extern struct key *request_key_with_auxdata(struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const void *callout_info, const void *callout_info,
size_t callout_len, size_t callout_len,
void *aux); void *aux);
/**
* request_key - Request a key and wait for construction
* @type: Type of key.
* @description: The searchable description of the key.
* @callout_info: The data to pass to the instantiation upcall (or NULL).
*
* As for request_key_tag(), but with the default global domain tag.
*/
static inline struct key *request_key(struct key_type *type,
const char *description,
const char *callout_info)
{
return request_key_tag(type, description, NULL, callout_info);
}
#ifdef CONFIG_NET
/*
* request_key_net - Request a key for a net namespace and wait for construction
* @type: Type of key.
* @description: The searchable description of the key.
* @net: The network namespace that is the key's domain of operation.
* @callout_info: The data to pass to the instantiation upcall (or NULL).
*
* As for request_key() except that it does not add the returned key to a
* keyring if found, new keys are always allocated in the user's quota, the
* callout_info must be a NUL-terminated string and no auxiliary data can be
* passed. Only keys that operate the specified network namespace are used.
*
* Furthermore, it then works as wait_for_key_construction() to wait for the
* completion of keys undergoing construction with a non-interruptible wait.
*/
#define request_key_net(type, description, net, callout_info) \
request_key_tag(type, description, net->key_domain, callout_info);
#endif /* CONFIG_NET */
extern int wait_for_key_construction(struct key *key, bool intr); extern int wait_for_key_construction(struct key *key, bool intr);
extern int key_validate(const struct key *key); extern int key_validate(const struct key *key);
......
...@@ -1887,7 +1887,8 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen, ...@@ -1887,7 +1887,8 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen,
return -EINVAL; return -EINVAL;
/* do dns_resolve upcall */ /* do dns_resolve upcall */
ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL, false); ip_len = dns_query(current->nsproxy->net_ns,
NULL, name, end - name, NULL, &ip_addr, NULL, false);
if (ip_len > 0) if (ip_len > 0)
ret = ceph_pton(ip_addr, ip_len, addr, -1, NULL); ret = ceph_pton(ip_addr, ip_len, addr, -1, NULL);
else else
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/cred.h> #include <linux/cred.h>
#include <linux/dns_resolver.h> #include <linux/dns_resolver.h>
#include <linux/err.h> #include <linux/err.h>
#include <net/net_namespace.h>
#include <keys/dns_resolver-type.h> #include <keys/dns_resolver-type.h>
#include <keys/user-type.h> #include <keys/user-type.h>
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
/** /**
* dns_query - Query the DNS * dns_query - Query the DNS
* @net: The network namespace to operate in.
* @type: Query type (or NULL for straight host->IP lookup) * @type: Query type (or NULL for straight host->IP lookup)
* @name: Name to look up * @name: Name to look up
* @namelen: Length of name * @namelen: Length of name
...@@ -69,7 +71,8 @@ ...@@ -69,7 +71,8 @@
* *
* Returns the size of the result on success, -ve error code otherwise. * Returns the size of the result on success, -ve error code otherwise.
*/ */
int dns_query(const char *type, const char *name, size_t namelen, int dns_query(struct net *net,
const char *type, const char *name, size_t namelen,
const char *options, char **_result, time64_t *_expiry, const char *options, char **_result, time64_t *_expiry,
bool invalidate) bool invalidate)
{ {
...@@ -122,7 +125,7 @@ int dns_query(const char *type, const char *name, size_t namelen, ...@@ -122,7 +125,7 @@ int dns_query(const char *type, const char *name, size_t namelen,
* add_key() to preinstall malicious redirections * add_key() to preinstall malicious redirections
*/ */
saved_cred = override_creds(dns_resolver_cache); saved_cred = override_creds(dns_resolver_cache);
rkey = request_key(&key_type_dns_resolver, desc, options); rkey = request_key_net(&key_type_dns_resolver, desc, net, options);
revert_creds(saved_cred); revert_creds(saved_cred);
kfree(desc); kfree(desc);
if (IS_ERR(rkey)) { if (IS_ERR(rkey)) {
......
...@@ -914,7 +914,7 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen) ...@@ -914,7 +914,7 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
if (IS_ERR(description)) if (IS_ERR(description))
return PTR_ERR(description); return PTR_ERR(description);
key = request_key(&key_type_rxrpc, description, NULL); key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL);
if (IS_ERR(key)) { if (IS_ERR(key)) {
kfree(description); kfree(description);
_leave(" = %ld", PTR_ERR(key)); _leave(" = %ld", PTR_ERR(key));
...@@ -945,7 +945,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval, ...@@ -945,7 +945,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
if (IS_ERR(description)) if (IS_ERR(description))
return PTR_ERR(description); return PTR_ERR(description);
key = request_key(&key_type_keyring, description, NULL); key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk), NULL);
if (IS_ERR(key)) { if (IS_ERR(key)) {
kfree(description); kfree(description);
_leave(" = %ld", PTR_ERR(key)); _leave(" = %ld", PTR_ERR(key));
......
...@@ -156,6 +156,7 @@ extern int install_session_keyring_to_cred(struct cred *, struct key *); ...@@ -156,6 +156,7 @@ extern int install_session_keyring_to_cred(struct cred *, struct key *);
extern struct key *request_key_and_link(struct key_type *type, extern struct key *request_key_and_link(struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const void *callout_info, const void *callout_info,
size_t callout_len, size_t callout_len,
void *aux, void *aux,
......
...@@ -224,7 +224,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, ...@@ -224,7 +224,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
} }
/* do the search */ /* do the search */
key = request_key_and_link(ktype, description, callout_info, key = request_key_and_link(ktype, description, NULL, callout_info,
callout_len, NULL, key_ref_to_ptr(dest_ref), callout_len, NULL, key_ref_to_ptr(dest_ref),
KEY_ALLOC_IN_QUOTA); KEY_ALLOC_IN_QUOTA);
if (IS_ERR(key)) { if (IS_ERR(key)) {
......
...@@ -222,10 +222,13 @@ void key_set_index_key(struct keyring_index_key *index_key) ...@@ -222,10 +222,13 @@ 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);
if (!index_key->domain_tag) {
if (index_key->type->flags & KEY_TYPE_NET_DOMAIN) if (index_key->type->flags & KEY_TYPE_NET_DOMAIN)
index_key->domain_tag = current->nsproxy->net_ns->key_domain; index_key->domain_tag = current->nsproxy->net_ns->key_domain;
else else
index_key->domain_tag = &default_domain_tag; index_key->domain_tag = &default_domain_tag;
}
hash_key_type_and_desc(index_key); hash_key_type_and_desc(index_key);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <net/net_namespace.h>
#include "internal.h" #include "internal.h"
#include <keys/request_key_auth-type.h> #include <keys/request_key_auth-type.h>
...@@ -533,16 +534,18 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, ...@@ -533,16 +534,18 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
* request_key_and_link - Request a key and cache it in a keyring. * request_key_and_link - Request a key and cache it in a keyring.
* @type: The type of key we want. * @type: The type of key we want.
* @description: The searchable description of the key. * @description: The searchable description of the key.
* @domain_tag: The domain in which the key operates.
* @callout_info: The data to pass to the instantiation upcall (or NULL). * @callout_info: The data to pass to the instantiation upcall (or NULL).
* @callout_len: The length of callout_info. * @callout_len: The length of callout_info.
* @aux: Auxiliary data for the upcall. * @aux: Auxiliary data for the upcall.
* @dest_keyring: Where to cache the key. * @dest_keyring: Where to cache the key.
* @flags: Flags to key_alloc(). * @flags: Flags to key_alloc().
* *
* A key matching the specified criteria is searched for in the process's * A key matching the specified criteria (type, description, domain_tag) is
* keyrings and returned with its usage count incremented if found. Otherwise, * searched for in the process's keyrings and returned with its usage count
* if callout_info is not NULL, a key will be allocated and some service * incremented if found. Otherwise, if callout_info is not NULL, a key will be
* (probably in userspace) will be asked to instantiate it. * allocated and some service (probably in userspace) will be asked to
* instantiate it.
* *
* If successfully found or created, the key will be linked to the destination * If successfully found or created, the key will be linked to the destination
* keyring if one is provided. * keyring if one is provided.
...@@ -558,6 +561,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, ...@@ -558,6 +561,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
*/ */
struct key *request_key_and_link(struct key_type *type, struct key *request_key_and_link(struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const void *callout_info, const void *callout_info,
size_t callout_len, size_t callout_len,
void *aux, void *aux,
...@@ -566,6 +570,7 @@ struct key *request_key_and_link(struct key_type *type, ...@@ -566,6 +570,7 @@ struct key *request_key_and_link(struct key_type *type,
{ {
struct keyring_search_context ctx = { struct keyring_search_context ctx = {
.index_key.type = type, .index_key.type = type,
.index_key.domain_tag = domain_tag,
.index_key.description = description, .index_key.description = description,
.index_key.desc_len = strlen(description), .index_key.desc_len = strlen(description),
.cred = current_cred(), .cred = current_cred(),
...@@ -672,9 +677,10 @@ int wait_for_key_construction(struct key *key, bool intr) ...@@ -672,9 +677,10 @@ int wait_for_key_construction(struct key *key, bool intr)
EXPORT_SYMBOL(wait_for_key_construction); EXPORT_SYMBOL(wait_for_key_construction);
/** /**
* request_key - Request a key and wait for construction * request_key_tag - Request a key and wait for construction
* @type: Type of key. * @type: Type of key.
* @description: The searchable description of the key. * @description: The searchable description of the key.
* @domain_tag: The domain in which the key operates.
* @callout_info: The data to pass to the instantiation upcall (or NULL). * @callout_info: The data to pass to the instantiation upcall (or NULL).
* *
* As for request_key_and_link() except that it does not add the returned key * As for request_key_and_link() except that it does not add the returned key
...@@ -685,8 +691,9 @@ EXPORT_SYMBOL(wait_for_key_construction); ...@@ -685,8 +691,9 @@ EXPORT_SYMBOL(wait_for_key_construction);
* Furthermore, it then works as wait_for_key_construction() to wait for the * Furthermore, it then works as wait_for_key_construction() to wait for the
* completion of keys undergoing construction with a non-interruptible wait. * completion of keys undergoing construction with a non-interruptible wait.
*/ */
struct key *request_key(struct key_type *type, struct key *request_key_tag(struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const char *callout_info) const char *callout_info)
{ {
struct key *key; struct key *key;
...@@ -695,7 +702,8 @@ struct key *request_key(struct key_type *type, ...@@ -695,7 +702,8 @@ struct key *request_key(struct key_type *type,
if (callout_info) if (callout_info)
callout_len = strlen(callout_info); callout_len = strlen(callout_info);
key = request_key_and_link(type, description, callout_info, callout_len, key = request_key_and_link(type, description, domain_tag,
callout_info, callout_len,
NULL, NULL, KEY_ALLOC_IN_QUOTA); NULL, NULL, KEY_ALLOC_IN_QUOTA);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
ret = wait_for_key_construction(key, false); ret = wait_for_key_construction(key, false);
...@@ -706,12 +714,13 @@ struct key *request_key(struct key_type *type, ...@@ -706,12 +714,13 @@ struct key *request_key(struct key_type *type,
} }
return key; return key;
} }
EXPORT_SYMBOL(request_key); EXPORT_SYMBOL(request_key_tag);
/** /**
* request_key_with_auxdata - Request a key with auxiliary data for the upcaller * request_key_with_auxdata - Request a key with auxiliary data for the upcaller
* @type: The type of key we want. * @type: The type of key we want.
* @description: The searchable description of the key. * @description: The searchable description of the key.
* @domain_tag: The domain in which the key operates.
* @callout_info: The data to pass to the instantiation upcall (or NULL). * @callout_info: The data to pass to the instantiation upcall (or NULL).
* @callout_len: The length of callout_info. * @callout_len: The length of callout_info.
* @aux: Auxiliary data for the upcall. * @aux: Auxiliary data for the upcall.
...@@ -724,6 +733,7 @@ EXPORT_SYMBOL(request_key); ...@@ -724,6 +733,7 @@ EXPORT_SYMBOL(request_key);
*/ */
struct key *request_key_with_auxdata(struct key_type *type, struct key *request_key_with_auxdata(struct key_type *type,
const char *description, const char *description,
struct key_tag *domain_tag,
const void *callout_info, const void *callout_info,
size_t callout_len, size_t callout_len,
void *aux) void *aux)
...@@ -731,7 +741,8 @@ struct key *request_key_with_auxdata(struct key_type *type, ...@@ -731,7 +741,8 @@ struct key *request_key_with_auxdata(struct key_type *type,
struct key *key; struct key *key;
int ret; int ret;
key = request_key_and_link(type, description, callout_info, callout_len, key = request_key_and_link(type, description, domain_tag,
callout_info, callout_len,
aux, NULL, KEY_ALLOC_IN_QUOTA); aux, NULL, KEY_ALLOC_IN_QUOTA);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
ret = wait_for_key_construction(key, false); ret = wait_for_key_construction(key, false);
...@@ -748,6 +759,7 @@ EXPORT_SYMBOL(request_key_with_auxdata); ...@@ -748,6 +759,7 @@ EXPORT_SYMBOL(request_key_with_auxdata);
* request_key_rcu - Request key from RCU-read-locked context * request_key_rcu - Request key from RCU-read-locked context
* @type: The type of key we want. * @type: The type of key we want.
* @description: The name of the key we want. * @description: The name of the key we want.
* @domain_tag: The domain in which the key operates.
* *
* Request a key from a context that we may not sleep in (such as RCU-mode * Request a key from a context that we may not sleep in (such as RCU-mode
* pathwalk). Keys under construction are ignored. * pathwalk). Keys under construction are ignored.
...@@ -755,10 +767,13 @@ EXPORT_SYMBOL(request_key_with_auxdata); ...@@ -755,10 +767,13 @@ EXPORT_SYMBOL(request_key_with_auxdata);
* Return a pointer to the found key if successful, -ENOKEY if we couldn't find * Return a pointer to the found key if successful, -ENOKEY if we couldn't find
* a key or some other error if the key found was unsuitable or inaccessible. * a key or some other error if the key found was unsuitable or inaccessible.
*/ */
struct key *request_key_rcu(struct key_type *type, const char *description) struct key *request_key_rcu(struct key_type *type,
const char *description,
struct key_tag *domain_tag)
{ {
struct keyring_search_context ctx = { struct keyring_search_context ctx = {
.index_key.type = type, .index_key.type = type,
.index_key.domain_tag = domain_tag,
.index_key.description = description, .index_key.description = description,
.index_key.desc_len = strlen(description), .index_key.desc_len = strlen(description),
.cred = current_cred(), .cred = current_cred(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment