You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
KEYS: Merge the type-specific data with the payload data
Merge the type-specific data with the payload data into one four-word chunk as it seems pointless to keep them separate. Use user_key_payload() for accessing the payloads of overloaded user-defined keys. Signed-off-by: David Howells <dhowells@redhat.com> cc: linux-cifs@vger.kernel.org cc: ecryptfs@vger.kernel.org cc: linux-ext4@vger.kernel.org cc: linux-f2fs-devel@lists.sourceforge.net cc: linux-nfs@vger.kernel.org cc: ceph-devel@vger.kernel.org cc: linux-ima-devel@lists.sourceforge.net
This commit is contained in:
+31
-16
@@ -20,6 +20,16 @@
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
* Layout of key payload words.
|
||||
*/
|
||||
enum {
|
||||
big_key_data,
|
||||
big_key_path,
|
||||
big_key_path_2nd_part,
|
||||
big_key_len,
|
||||
};
|
||||
|
||||
/*
|
||||
* If the data is under this limit, there's no point creating a shm file to
|
||||
* hold it as the permanently resident metadata for the shmem fs will be at
|
||||
@@ -47,7 +57,7 @@ struct key_type key_type_big_key = {
|
||||
*/
|
||||
int big_key_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
struct path *path = (struct path *)&prep->payload;
|
||||
struct path *path = (struct path *)&prep->payload.data[big_key_path];
|
||||
struct file *file;
|
||||
ssize_t written;
|
||||
size_t datalen = prep->datalen;
|
||||
@@ -60,7 +70,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
|
||||
/* Set an arbitrary quota */
|
||||
prep->quotalen = 16;
|
||||
|
||||
prep->type_data[1] = (void *)(unsigned long)datalen;
|
||||
prep->payload.data[big_key_len] = (void *)(unsigned long)datalen;
|
||||
|
||||
if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||
/* Create a shmem file to store the data in. This will permit the data
|
||||
@@ -94,7 +104,8 @@ int big_key_preparse(struct key_preparsed_payload *prep)
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
prep->payload[0] = memcpy(data, prep->data, prep->datalen);
|
||||
prep->payload.data[big_key_data] = data;
|
||||
memcpy(data, prep->data, prep->datalen);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -110,10 +121,10 @@ error:
|
||||
void big_key_free_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||
struct path *path = (struct path *)&prep->payload;
|
||||
struct path *path = (struct path *)&prep->payload.data[big_key_path];
|
||||
path_put(path);
|
||||
} else {
|
||||
kfree(prep->payload[0]);
|
||||
kfree(prep->payload.data[big_key_data]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,11 +134,12 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
|
||||
*/
|
||||
void big_key_revoke(struct key *key)
|
||||
{
|
||||
struct path *path = (struct path *)&key->payload.data2;
|
||||
struct path *path = (struct path *)&key->payload.data[big_key_path];
|
||||
|
||||
/* clear the quota */
|
||||
key_payload_reserve(key, 0);
|
||||
if (key_is_instantiated(key) && key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD)
|
||||
if (key_is_instantiated(key) &&
|
||||
(size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
|
||||
vfs_truncate(path, 0);
|
||||
}
|
||||
|
||||
@@ -136,14 +148,16 @@ void big_key_revoke(struct key *key)
|
||||
*/
|
||||
void big_key_destroy(struct key *key)
|
||||
{
|
||||
if (key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) {
|
||||
struct path *path = (struct path *)&key->payload.data2;
|
||||
size_t datalen = (size_t)key->payload.data[big_key_len];
|
||||
|
||||
if (datalen) {
|
||||
struct path *path = (struct path *)&key->payload.data[big_key_path];
|
||||
path_put(path);
|
||||
path->mnt = NULL;
|
||||
path->dentry = NULL;
|
||||
} else {
|
||||
kfree(key->payload.data);
|
||||
key->payload.data = NULL;
|
||||
kfree(key->payload.data[big_key_data]);
|
||||
key->payload.data[big_key_data] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,12 +166,12 @@ void big_key_destroy(struct key *key)
|
||||
*/
|
||||
void big_key_describe(const struct key *key, struct seq_file *m)
|
||||
{
|
||||
unsigned long datalen = key->type_data.x[1];
|
||||
size_t datalen = (size_t)key->payload.data[big_key_len];
|
||||
|
||||
seq_puts(m, key->description);
|
||||
|
||||
if (key_is_instantiated(key))
|
||||
seq_printf(m, ": %lu [%s]",
|
||||
seq_printf(m, ": %zu [%s]",
|
||||
datalen,
|
||||
datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
|
||||
}
|
||||
@@ -168,14 +182,14 @@ void big_key_describe(const struct key *key, struct seq_file *m)
|
||||
*/
|
||||
long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
|
||||
{
|
||||
unsigned long datalen = key->type_data.x[1];
|
||||
size_t datalen = (size_t)key->payload.data[big_key_len];
|
||||
long ret;
|
||||
|
||||
if (!buffer || buflen < datalen)
|
||||
return datalen;
|
||||
|
||||
if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||
struct path *path = (struct path *)&key->payload.data2;
|
||||
struct path *path = (struct path *)&key->payload.data[big_key_path];
|
||||
struct file *file;
|
||||
loff_t pos;
|
||||
|
||||
@@ -190,7 +204,8 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
|
||||
ret = -EIO;
|
||||
} else {
|
||||
ret = datalen;
|
||||
if (copy_to_user(buffer, key->payload.data, datalen) != 0)
|
||||
if (copy_to_user(buffer, key->payload.data[big_key_data],
|
||||
datalen) != 0)
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
|
||||
@@ -303,10 +303,10 @@ out:
|
||||
*
|
||||
* Use a user provided key to encrypt/decrypt an encrypted-key.
|
||||
*/
|
||||
static struct key *request_user_key(const char *master_desc, u8 **master_key,
|
||||
static struct key *request_user_key(const char *master_desc, const u8 **master_key,
|
||||
size_t *master_keylen)
|
||||
{
|
||||
struct user_key_payload *upayload;
|
||||
const struct user_key_payload *upayload;
|
||||
struct key *ukey;
|
||||
|
||||
ukey = request_key(&key_type_user, master_desc, NULL);
|
||||
@@ -314,7 +314,7 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key,
|
||||
goto error;
|
||||
|
||||
down_read(&ukey->sem);
|
||||
upayload = ukey->payload.data;
|
||||
upayload = user_key_payload(ukey);
|
||||
*master_key = upayload->data;
|
||||
*master_keylen = upayload->datalen;
|
||||
error:
|
||||
@@ -426,7 +426,7 @@ static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key,
|
||||
}
|
||||
|
||||
static struct key *request_master_key(struct encrypted_key_payload *epayload,
|
||||
u8 **master_key, size_t *master_keylen)
|
||||
const u8 **master_key, size_t *master_keylen)
|
||||
{
|
||||
struct key *mkey = NULL;
|
||||
|
||||
@@ -653,7 +653,7 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
|
||||
{
|
||||
struct key *mkey;
|
||||
u8 derived_key[HASH_SIZE];
|
||||
u8 *master_key;
|
||||
const u8 *master_key;
|
||||
u8 *hmac;
|
||||
const char *hex_encoded_data;
|
||||
unsigned int encrypted_datalen;
|
||||
@@ -837,7 +837,7 @@ static void encrypted_rcu_free(struct rcu_head *rcu)
|
||||
*/
|
||||
static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
|
||||
{
|
||||
struct encrypted_key_payload *epayload = key->payload.data;
|
||||
struct encrypted_key_payload *epayload = key->payload.data[0];
|
||||
struct encrypted_key_payload *new_epayload;
|
||||
char *buf;
|
||||
char *new_master_desc = NULL;
|
||||
@@ -896,7 +896,7 @@ static long encrypted_read(const struct key *key, char __user *buffer,
|
||||
{
|
||||
struct encrypted_key_payload *epayload;
|
||||
struct key *mkey;
|
||||
u8 *master_key;
|
||||
const u8 *master_key;
|
||||
size_t master_keylen;
|
||||
char derived_key[HASH_SIZE];
|
||||
char *ascii_buf;
|
||||
@@ -957,13 +957,13 @@ out:
|
||||
*/
|
||||
static void encrypted_destroy(struct key *key)
|
||||
{
|
||||
struct encrypted_key_payload *epayload = key->payload.data;
|
||||
struct encrypted_key_payload *epayload = key->payload.data[0];
|
||||
|
||||
if (!epayload)
|
||||
return;
|
||||
|
||||
memset(epayload->decrypted_data, 0, epayload->decrypted_datalen);
|
||||
kfree(key->payload.data);
|
||||
kfree(key->payload.data[0]);
|
||||
}
|
||||
|
||||
struct key_type key_type_encrypted = {
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#if defined(CONFIG_TRUSTED_KEYS) || \
|
||||
(defined(CONFIG_TRUSTED_KEYS_MODULE) && defined(CONFIG_ENCRYPTED_KEYS_MODULE))
|
||||
extern struct key *request_trusted_key(const char *trusted_desc,
|
||||
u8 **master_key, size_t *master_keylen);
|
||||
const u8 **master_key, size_t *master_keylen);
|
||||
#else
|
||||
static inline struct key *request_trusted_key(const char *trusted_desc,
|
||||
u8 **master_key,
|
||||
const u8 **master_key,
|
||||
size_t *master_keylen)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* data, trusted key type data is not visible decrypted from userspace.
|
||||
*/
|
||||
struct key *request_trusted_key(const char *trusted_desc,
|
||||
u8 **master_key, size_t *master_keylen)
|
||||
const u8 **master_key, size_t *master_keylen)
|
||||
{
|
||||
struct trusted_key_payload *tpayload;
|
||||
struct key *tkey;
|
||||
@@ -39,7 +39,7 @@ struct key *request_trusted_key(const char *trusted_desc,
|
||||
goto error;
|
||||
|
||||
down_read(&tkey->sem);
|
||||
tpayload = tkey->payload.data;
|
||||
tpayload = tkey->payload.data[0];
|
||||
*master_key = tpayload->key;
|
||||
*master_keylen = tpayload->key_len;
|
||||
error:
|
||||
|
||||
+9
-9
@@ -554,7 +554,7 @@ int key_reject_and_link(struct key *key,
|
||||
if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
|
||||
/* mark the key as being negatively instantiated */
|
||||
atomic_inc(&key->user->nikeys);
|
||||
key->type_data.reject_error = -error;
|
||||
key->reject_error = -error;
|
||||
smp_wmb();
|
||||
set_bit(KEY_FLAG_NEGATIVE, &key->flags);
|
||||
set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
|
||||
@@ -1046,14 +1046,14 @@ int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
|
||||
|
||||
ret = key_payload_reserve(key, prep->quotalen);
|
||||
if (ret == 0) {
|
||||
key->type_data.p[0] = prep->type_data[0];
|
||||
key->type_data.p[1] = prep->type_data[1];
|
||||
rcu_assign_keypointer(key, prep->payload[0]);
|
||||
key->payload.data2[1] = prep->payload[1];
|
||||
prep->type_data[0] = NULL;
|
||||
prep->type_data[1] = NULL;
|
||||
prep->payload[0] = NULL;
|
||||
prep->payload[1] = NULL;
|
||||
rcu_assign_keypointer(key, prep->payload.data[0]);
|
||||
key->payload.data[1] = prep->payload.data[1];
|
||||
key->payload.data[2] = prep->payload.data[2];
|
||||
key->payload.data[3] = prep->payload.data[3];
|
||||
prep->payload.data[0] = NULL;
|
||||
prep->payload.data[1] = NULL;
|
||||
prep->payload.data[2] = NULL;
|
||||
prep->payload.data[3] = NULL;
|
||||
}
|
||||
pr_devel("<==%s() = %d\n", __func__, ret);
|
||||
return ret;
|
||||
|
||||
@@ -1027,7 +1027,7 @@ long keyctl_instantiate_key_common(key_serial_t id,
|
||||
if (!instkey)
|
||||
goto error;
|
||||
|
||||
rka = instkey->payload.data;
|
||||
rka = instkey->payload.data[0];
|
||||
if (rka->target_key->serial != id)
|
||||
goto error;
|
||||
|
||||
@@ -1194,7 +1194,7 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error,
|
||||
if (!instkey)
|
||||
goto error;
|
||||
|
||||
rka = instkey->payload.data;
|
||||
rka = instkey->payload.data[0];
|
||||
if (rka->target_key->serial != id)
|
||||
goto error;
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ static void keyring_publish_name(struct key *keyring)
|
||||
if (!keyring_name_hash[bucket].next)
|
||||
INIT_LIST_HEAD(&keyring_name_hash[bucket]);
|
||||
|
||||
list_add_tail(&keyring->type_data.link,
|
||||
list_add_tail(&keyring->name_link,
|
||||
&keyring_name_hash[bucket]);
|
||||
|
||||
write_unlock(&keyring_name_lock);
|
||||
@@ -387,9 +387,9 @@ static void keyring_destroy(struct key *keyring)
|
||||
if (keyring->description) {
|
||||
write_lock(&keyring_name_lock);
|
||||
|
||||
if (keyring->type_data.link.next != NULL &&
|
||||
!list_empty(&keyring->type_data.link))
|
||||
list_del(&keyring->type_data.link);
|
||||
if (keyring->name_link.next != NULL &&
|
||||
!list_empty(&keyring->name_link))
|
||||
list_del(&keyring->name_link);
|
||||
|
||||
write_unlock(&keyring_name_lock);
|
||||
}
|
||||
@@ -572,7 +572,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
|
||||
/* we set a different error code if we pass a negative key */
|
||||
if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
|
||||
smp_rmb();
|
||||
ctx->result = ERR_PTR(key->type_data.reject_error);
|
||||
ctx->result = ERR_PTR(key->reject_error);
|
||||
kleave(" = %d [neg]", ctx->skipped_ret);
|
||||
goto skipped;
|
||||
}
|
||||
@@ -990,7 +990,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
|
||||
* that's readable and that hasn't been revoked */
|
||||
list_for_each_entry(keyring,
|
||||
&keyring_name_hash[bucket],
|
||||
type_data.link
|
||||
name_link
|
||||
) {
|
||||
if (!kuid_has_mapping(current_user_ns(), keyring->user->uid))
|
||||
continue;
|
||||
|
||||
@@ -457,7 +457,7 @@ key_ref_t search_process_keyrings(struct keyring_search_context *ctx)
|
||||
down_read(&cred->request_key_auth->sem);
|
||||
|
||||
if (key_validate(ctx->cred->request_key_auth) == 0) {
|
||||
rka = ctx->cred->request_key_auth->payload.data;
|
||||
rka = ctx->cred->request_key_auth->payload.data[0];
|
||||
|
||||
ctx->cred = rka->cred;
|
||||
key_ref = search_process_keyrings(ctx);
|
||||
@@ -647,7 +647,7 @@ try_again:
|
||||
key_ref = ERR_PTR(-EKEYREVOKED);
|
||||
key = NULL;
|
||||
} else {
|
||||
rka = ctx.cred->request_key_auth->payload.data;
|
||||
rka = ctx.cred->request_key_auth->payload.data[0];
|
||||
key = rka->dest_keyring;
|
||||
__key_get(key);
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ static void construct_get_dest_keyring(struct key **_dest_keyring)
|
||||
if (cred->request_key_auth) {
|
||||
authkey = cred->request_key_auth;
|
||||
down_read(&authkey->sem);
|
||||
rka = authkey->payload.data;
|
||||
rka = authkey->payload.data[0];
|
||||
if (!test_bit(KEY_FLAG_REVOKED,
|
||||
&authkey->flags))
|
||||
dest_keyring =
|
||||
@@ -593,7 +593,7 @@ int wait_for_key_construction(struct key *key, bool intr)
|
||||
return -ERESTARTSYS;
|
||||
if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
|
||||
smp_rmb();
|
||||
return key->type_data.reject_error;
|
||||
return key->reject_error;
|
||||
}
|
||||
return key_validate(key);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
|
||||
static int request_key_auth_instantiate(struct key *key,
|
||||
struct key_preparsed_payload *prep)
|
||||
{
|
||||
key->payload.data = (struct request_key_auth *)prep->data;
|
||||
key->payload.data[0] = (struct request_key_auth *)prep->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ static int request_key_auth_instantiate(struct key *key,
|
||||
static void request_key_auth_describe(const struct key *key,
|
||||
struct seq_file *m)
|
||||
{
|
||||
struct request_key_auth *rka = key->payload.data;
|
||||
struct request_key_auth *rka = key->payload.data[0];
|
||||
|
||||
seq_puts(m, "key:");
|
||||
seq_puts(m, key->description);
|
||||
@@ -84,7 +84,7 @@ static void request_key_auth_describe(const struct key *key,
|
||||
static long request_key_auth_read(const struct key *key,
|
||||
char __user *buffer, size_t buflen)
|
||||
{
|
||||
struct request_key_auth *rka = key->payload.data;
|
||||
struct request_key_auth *rka = key->payload.data[0];
|
||||
size_t datalen;
|
||||
long ret;
|
||||
|
||||
@@ -110,7 +110,7 @@ static long request_key_auth_read(const struct key *key,
|
||||
*/
|
||||
static void request_key_auth_revoke(struct key *key)
|
||||
{
|
||||
struct request_key_auth *rka = key->payload.data;
|
||||
struct request_key_auth *rka = key->payload.data[0];
|
||||
|
||||
kenter("{%d}", key->serial);
|
||||
|
||||
@@ -125,7 +125,7 @@ static void request_key_auth_revoke(struct key *key)
|
||||
*/
|
||||
static void request_key_auth_destroy(struct key *key)
|
||||
{
|
||||
struct request_key_auth *rka = key->payload.data;
|
||||
struct request_key_auth *rka = key->payload.data[0];
|
||||
|
||||
kenter("{%d}", key->serial);
|
||||
|
||||
@@ -179,7 +179,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
|
||||
if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
|
||||
goto auth_key_revoked;
|
||||
|
||||
irka = cred->request_key_auth->payload.data;
|
||||
irka = cred->request_key_auth->payload.data[0];
|
||||
rka->cred = get_cred(irka->cred);
|
||||
rka->pid = irka->pid;
|
||||
|
||||
|
||||
@@ -1007,7 +1007,7 @@ static void trusted_rcu_free(struct rcu_head *rcu)
|
||||
*/
|
||||
static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
|
||||
{
|
||||
struct trusted_key_payload *p = key->payload.data;
|
||||
struct trusted_key_payload *p = key->payload.data[0];
|
||||
struct trusted_key_payload *new_p;
|
||||
struct trusted_key_options *new_o;
|
||||
size_t datalen = prep->datalen;
|
||||
@@ -1114,12 +1114,12 @@ static long trusted_read(const struct key *key, char __user *buffer,
|
||||
*/
|
||||
static void trusted_destroy(struct key *key)
|
||||
{
|
||||
struct trusted_key_payload *p = key->payload.data;
|
||||
struct trusted_key_payload *p = key->payload.data[0];
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
memset(p->key, 0, p->key_len);
|
||||
kfree(key->payload.data);
|
||||
kfree(key->payload.data[0]);
|
||||
}
|
||||
|
||||
struct key_type key_type_trusted = {
|
||||
|
||||
@@ -74,7 +74,7 @@ int user_preparse(struct key_preparsed_payload *prep)
|
||||
|
||||
/* attach the data */
|
||||
prep->quotalen = datalen;
|
||||
prep->payload[0] = upayload;
|
||||
prep->payload.data[0] = upayload;
|
||||
upayload->datalen = datalen;
|
||||
memcpy(upayload->data, prep->data, datalen);
|
||||
return 0;
|
||||
@@ -86,7 +86,7 @@ EXPORT_SYMBOL_GPL(user_preparse);
|
||||
*/
|
||||
void user_free_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
kfree(prep->payload[0]);
|
||||
kfree(prep->payload.data[0]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(user_free_preparse);
|
||||
|
||||
@@ -120,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
|
||||
|
||||
if (ret == 0) {
|
||||
/* attach the new data, displacing the old */
|
||||
zap = key->payload.data;
|
||||
zap = key->payload.data[0];
|
||||
rcu_assign_keypointer(key, upayload);
|
||||
key->expiry = 0;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ EXPORT_SYMBOL_GPL(user_update);
|
||||
*/
|
||||
void user_revoke(struct key *key)
|
||||
{
|
||||
struct user_key_payload *upayload = key->payload.data;
|
||||
struct user_key_payload *upayload = key->payload.data[0];
|
||||
|
||||
/* clear the quota */
|
||||
key_payload_reserve(key, 0);
|
||||
@@ -158,7 +158,7 @@ EXPORT_SYMBOL(user_revoke);
|
||||
*/
|
||||
void user_destroy(struct key *key)
|
||||
{
|
||||
struct user_key_payload *upayload = key->payload.data;
|
||||
struct user_key_payload *upayload = key->payload.data[0];
|
||||
|
||||
kfree(upayload);
|
||||
}
|
||||
@@ -183,10 +183,10 @@ EXPORT_SYMBOL_GPL(user_describe);
|
||||
*/
|
||||
long user_read(const struct key *key, char __user *buffer, size_t buflen)
|
||||
{
|
||||
struct user_key_payload *upayload;
|
||||
const struct user_key_payload *upayload;
|
||||
long ret;
|
||||
|
||||
upayload = rcu_dereference_key(key);
|
||||
upayload = user_key_payload(key);
|
||||
ret = upayload->datalen;
|
||||
|
||||
/* we can return the data as is */
|
||||
|
||||
Reference in New Issue
Block a user