mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-21 06:24:12 +00:00
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: 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
9b24261051
commit
a58946c158
16 changed files with 145 additions and 49 deletions
|
@ -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
|
||||||
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::
|
||||||
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
|
||||||
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_rcu() call is like the in-kernel request_key() call, except
|
The request_key_with_auxdata() calls is like the request_key_tag() call, except
|
||||||
that it doesn't check for keys that are under construction and doesn't attempt
|
that they permit auxiliary data to be passed to the upcaller (the default is
|
||||||
to construct missing keys.
|
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 request_key_tag() call, except that it
|
||||||
|
doesn't check for keys that are under construction and doesn't attempt to
|
||||||
|
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
|
||||||
|
|
||||||
_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 = {
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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 @@
|
||||||
|
|
||||||
#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;
|
||||||
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)
|
||||||
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,
|
||||||
const char *callout_info);
|
struct key_tag *domain_tag,
|
||||||
|
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,
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 @@
|
||||||
*
|
*
|
||||||
* 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,
|
||||||
* 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)
|
||||||
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,
|
||||||
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 *);
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|
||||||
memcpy(index_key->desc, index_key->description, n);
|
memcpy(index_key->desc, index_key->description, n);
|
||||||
|
|
||||||
if (index_key->type->flags & KEY_TYPE_NET_DOMAIN)
|
if (!index_key->domain_tag) {
|
||||||
index_key->domain_tag = current->nsproxy->net_ns->key_domain;
|
if (index_key->type->flags & KEY_TYPE_NET_DOMAIN)
|
||||||
else
|
index_key->domain_tag = current->nsproxy->net_ns->key_domain;
|
||||||
index_key->domain_tag = &default_domain_tag;
|
else
|
||||||
|
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 @@
|
||||||
#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 @@ error:
|
||||||
* 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 @@ error:
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
{
|
{
|
||||||
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)
|
||||||
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,9 +691,10 @@ 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,
|
||||||
const char *callout_info)
|
struct key_tag *domain_tag,
|
||||||
|
const char *callout_info)
|
||||||
{
|
{
|
||||||
struct key *key;
|
struct key *key;
|
||||||
size_t callout_len = 0;
|
size_t callout_len = 0;
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
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);
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
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);
|
||||||
* 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);
|
||||||
* 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(),
|
||||||
|
|
Loading…
Add table
Reference in a new issue