mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 00:20:32 +00:00
KEYS: Consolidate the concept of an 'index key' for key access
Consolidate the concept of an 'index key' for accessing keys. The index key is the search term needed to find a key directly - basically the key type and the key description. We can add to that the description length. This will be useful when turning a keyring into an associative array rather than just a pointer block. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
7e55ca6dcd
commit
16feef4340
5 changed files with 83 additions and 67 deletions
|
@ -82,6 +82,12 @@ struct key_owner;
|
||||||
struct keyring_list;
|
struct keyring_list;
|
||||||
struct keyring_name;
|
struct keyring_name;
|
||||||
|
|
||||||
|
struct keyring_index_key {
|
||||||
|
struct key_type *type;
|
||||||
|
const char *description;
|
||||||
|
size_t desc_len;
|
||||||
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* key reference with possession attribute handling
|
* key reference with possession attribute handling
|
||||||
|
@ -129,7 +135,6 @@ struct key {
|
||||||
struct list_head graveyard_link;
|
struct list_head graveyard_link;
|
||||||
struct rb_node serial_node;
|
struct rb_node serial_node;
|
||||||
};
|
};
|
||||||
struct key_type *type; /* type of key */
|
|
||||||
struct rw_semaphore sem; /* change vs change sem */
|
struct rw_semaphore sem; /* change vs change sem */
|
||||||
struct key_user *user; /* owner of this key */
|
struct key_user *user; /* owner of this key */
|
||||||
void *security; /* security data for this key */
|
void *security; /* security data for this key */
|
||||||
|
@ -163,12 +168,18 @@ struct key {
|
||||||
#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
|
#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
|
||||||
#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
|
#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
|
||||||
|
|
||||||
/* the description string
|
/* the key type and key description string
|
||||||
* - this is used to match a key against search criteria
|
* - the desc is used to match a key against search criteria
|
||||||
* - this should be a printable string
|
* - it should be a printable string
|
||||||
* - eg: for krb5 AFS, this might be "afs@REDHAT.COM"
|
* - eg: for krb5 AFS, this might be "afs@REDHAT.COM"
|
||||||
*/
|
*/
|
||||||
char *description;
|
union {
|
||||||
|
struct keyring_index_key index_key;
|
||||||
|
struct {
|
||||||
|
struct key_type *type; /* type of key */
|
||||||
|
char *description;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/* type specific data
|
/* type specific data
|
||||||
* - this is used by the keyring type to index the name
|
* - this is used by the keyring type to index the name
|
||||||
|
|
|
@ -89,19 +89,17 @@ extern struct key_type *key_type_lookup(const char *type);
|
||||||
extern void key_type_put(struct key_type *ktype);
|
extern void key_type_put(struct key_type *ktype);
|
||||||
|
|
||||||
extern int __key_link_begin(struct key *keyring,
|
extern int __key_link_begin(struct key *keyring,
|
||||||
const struct key_type *type,
|
const struct keyring_index_key *index_key,
|
||||||
const char *description,
|
|
||||||
unsigned long *_prealloc);
|
unsigned long *_prealloc);
|
||||||
extern int __key_link_check_live_key(struct key *keyring, struct key *key);
|
extern int __key_link_check_live_key(struct key *keyring, struct key *key);
|
||||||
extern void __key_link(struct key *keyring, struct key *key,
|
extern void __key_link(struct key *keyring, struct key *key,
|
||||||
unsigned long *_prealloc);
|
unsigned long *_prealloc);
|
||||||
extern void __key_link_end(struct key *keyring,
|
extern void __key_link_end(struct key *keyring,
|
||||||
struct key_type *type,
|
const struct keyring_index_key *index_key,
|
||||||
unsigned long prealloc);
|
unsigned long prealloc);
|
||||||
|
|
||||||
extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
|
extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
|
||||||
const struct key_type *type,
|
const struct keyring_index_key *index_key,
|
||||||
const char *description,
|
|
||||||
key_perm_t perm);
|
key_perm_t perm);
|
||||||
|
|
||||||
extern struct key *keyring_search_instkey(struct key *keyring,
|
extern struct key *keyring_search_instkey(struct key *keyring,
|
||||||
|
|
|
@ -242,8 +242,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
desclen = strlen(desc) + 1;
|
desclen = strlen(desc);
|
||||||
quotalen = desclen + type->def_datalen;
|
quotalen = desclen + 1 + type->def_datalen;
|
||||||
|
|
||||||
/* get hold of the key tracking for this user */
|
/* get hold of the key tracking for this user */
|
||||||
user = key_user_lookup(uid);
|
user = key_user_lookup(uid);
|
||||||
|
@ -277,7 +277,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
|
||||||
goto no_memory_2;
|
goto no_memory_2;
|
||||||
|
|
||||||
if (desc) {
|
if (desc) {
|
||||||
key->description = kmemdup(desc, desclen, GFP_KERNEL);
|
key->index_key.desc_len = desclen;
|
||||||
|
key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL);
|
||||||
if (!key->description)
|
if (!key->description)
|
||||||
goto no_memory_3;
|
goto no_memory_3;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +286,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
|
||||||
atomic_set(&key->usage, 1);
|
atomic_set(&key->usage, 1);
|
||||||
init_rwsem(&key->sem);
|
init_rwsem(&key->sem);
|
||||||
lockdep_set_class(&key->sem, &type->lock_class);
|
lockdep_set_class(&key->sem, &type->lock_class);
|
||||||
key->type = type;
|
key->index_key.type = type;
|
||||||
key->user = user;
|
key->user = user;
|
||||||
key->quotalen = quotalen;
|
key->quotalen = quotalen;
|
||||||
key->datalen = type->def_datalen;
|
key->datalen = type->def_datalen;
|
||||||
|
@ -489,8 +490,7 @@ int key_instantiate_and_link(struct key *key,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyring) {
|
if (keyring) {
|
||||||
ret = __key_link_begin(keyring, key->type, key->description,
|
ret = __key_link_begin(keyring, &key->index_key, &prealloc);
|
||||||
&prealloc);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_free_preparse;
|
goto error_free_preparse;
|
||||||
}
|
}
|
||||||
|
@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key,
|
||||||
&prealloc);
|
&prealloc);
|
||||||
|
|
||||||
if (keyring)
|
if (keyring)
|
||||||
__key_link_end(keyring, key->type, prealloc);
|
__key_link_end(keyring, &key->index_key, prealloc);
|
||||||
|
|
||||||
error_free_preparse:
|
error_free_preparse:
|
||||||
if (key->type->preparse)
|
if (key->type->preparse)
|
||||||
|
@ -548,8 +548,7 @@ int key_reject_and_link(struct key *key,
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
|
||||||
if (keyring)
|
if (keyring)
|
||||||
link_ret = __key_link_begin(keyring, key->type,
|
link_ret = __key_link_begin(keyring, &key->index_key, &prealloc);
|
||||||
key->description, &prealloc);
|
|
||||||
|
|
||||||
mutex_lock(&key_construction_mutex);
|
mutex_lock(&key_construction_mutex);
|
||||||
|
|
||||||
|
@ -581,7 +580,7 @@ int key_reject_and_link(struct key *key,
|
||||||
mutex_unlock(&key_construction_mutex);
|
mutex_unlock(&key_construction_mutex);
|
||||||
|
|
||||||
if (keyring)
|
if (keyring)
|
||||||
__key_link_end(keyring, key->type, prealloc);
|
__key_link_end(keyring, &key->index_key, prealloc);
|
||||||
|
|
||||||
/* wake up anyone waiting for a key to be constructed */
|
/* wake up anyone waiting for a key to be constructed */
|
||||||
if (awaken)
|
if (awaken)
|
||||||
|
@ -780,25 +779,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||||
key_perm_t perm,
|
key_perm_t perm,
|
||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
unsigned long prealloc;
|
struct keyring_index_key index_key = {
|
||||||
|
.description = description,
|
||||||
|
};
|
||||||
struct key_preparsed_payload prep;
|
struct key_preparsed_payload prep;
|
||||||
const struct cred *cred = current_cred();
|
const struct cred *cred = current_cred();
|
||||||
struct key_type *ktype;
|
unsigned long prealloc;
|
||||||
struct key *keyring, *key = NULL;
|
struct key *keyring, *key = NULL;
|
||||||
key_ref_t key_ref;
|
key_ref_t key_ref;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* look up the key type to see if it's one of the registered kernel
|
/* look up the key type to see if it's one of the registered kernel
|
||||||
* types */
|
* types */
|
||||||
ktype = key_type_lookup(type);
|
index_key.type = key_type_lookup(type);
|
||||||
if (IS_ERR(ktype)) {
|
if (IS_ERR(index_key.type)) {
|
||||||
key_ref = ERR_PTR(-ENODEV);
|
key_ref = ERR_PTR(-ENODEV);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_ref = ERR_PTR(-EINVAL);
|
key_ref = ERR_PTR(-EINVAL);
|
||||||
if (!ktype->match || !ktype->instantiate ||
|
if (!index_key.type->match || !index_key.type->instantiate ||
|
||||||
(!description && !ktype->preparse))
|
(!index_key.description && !index_key.type->preparse))
|
||||||
goto error_put_type;
|
goto error_put_type;
|
||||||
|
|
||||||
keyring = key_ref_to_ptr(keyring_ref);
|
keyring = key_ref_to_ptr(keyring_ref);
|
||||||
|
@ -812,21 +813,22 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||||
memset(&prep, 0, sizeof(prep));
|
memset(&prep, 0, sizeof(prep));
|
||||||
prep.data = payload;
|
prep.data = payload;
|
||||||
prep.datalen = plen;
|
prep.datalen = plen;
|
||||||
prep.quotalen = ktype->def_datalen;
|
prep.quotalen = index_key.type->def_datalen;
|
||||||
if (ktype->preparse) {
|
if (index_key.type->preparse) {
|
||||||
ret = ktype->preparse(&prep);
|
ret = index_key.type->preparse(&prep);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
key_ref = ERR_PTR(ret);
|
key_ref = ERR_PTR(ret);
|
||||||
goto error_put_type;
|
goto error_put_type;
|
||||||
}
|
}
|
||||||
if (!description)
|
if (!index_key.description)
|
||||||
description = prep.description;
|
index_key.description = prep.description;
|
||||||
key_ref = ERR_PTR(-EINVAL);
|
key_ref = ERR_PTR(-EINVAL);
|
||||||
if (!description)
|
if (!index_key.description)
|
||||||
goto error_free_prep;
|
goto error_free_prep;
|
||||||
}
|
}
|
||||||
|
index_key.desc_len = strlen(index_key.description);
|
||||||
|
|
||||||
ret = __key_link_begin(keyring, ktype, description, &prealloc);
|
ret = __key_link_begin(keyring, &index_key, &prealloc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
key_ref = ERR_PTR(ret);
|
key_ref = ERR_PTR(ret);
|
||||||
goto error_free_prep;
|
goto error_free_prep;
|
||||||
|
@ -844,9 +846,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||||
* key of the same type and description in the destination keyring and
|
* key of the same type and description in the destination keyring and
|
||||||
* update that instead if possible
|
* update that instead if possible
|
||||||
*/
|
*/
|
||||||
if (ktype->update) {
|
if (index_key.type->update) {
|
||||||
key_ref = __keyring_search_one(keyring_ref, ktype, description,
|
key_ref = __keyring_search_one(keyring_ref, &index_key, 0);
|
||||||
0);
|
|
||||||
if (!IS_ERR(key_ref))
|
if (!IS_ERR(key_ref))
|
||||||
goto found_matching_key;
|
goto found_matching_key;
|
||||||
}
|
}
|
||||||
|
@ -856,16 +857,17 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||||
perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
|
perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
|
||||||
perm |= KEY_USR_VIEW;
|
perm |= KEY_USR_VIEW;
|
||||||
|
|
||||||
if (ktype->read)
|
if (index_key.type->read)
|
||||||
perm |= KEY_POS_READ;
|
perm |= KEY_POS_READ;
|
||||||
|
|
||||||
if (ktype == &key_type_keyring || ktype->update)
|
if (index_key.type == &key_type_keyring ||
|
||||||
|
index_key.type->update)
|
||||||
perm |= KEY_POS_WRITE;
|
perm |= KEY_POS_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate a new key */
|
/* allocate a new key */
|
||||||
key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred,
|
key = key_alloc(index_key.type, index_key.description,
|
||||||
perm, flags);
|
cred->fsuid, cred->fsgid, cred, perm, flags);
|
||||||
if (IS_ERR(key)) {
|
if (IS_ERR(key)) {
|
||||||
key_ref = ERR_CAST(key);
|
key_ref = ERR_CAST(key);
|
||||||
goto error_link_end;
|
goto error_link_end;
|
||||||
|
@ -882,12 +884,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||||
key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
|
key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
|
||||||
|
|
||||||
error_link_end:
|
error_link_end:
|
||||||
__key_link_end(keyring, ktype, prealloc);
|
__key_link_end(keyring, &index_key, prealloc);
|
||||||
error_free_prep:
|
error_free_prep:
|
||||||
if (ktype->preparse)
|
if (index_key.type->preparse)
|
||||||
ktype->free_preparse(&prep);
|
index_key.type->free_preparse(&prep);
|
||||||
error_put_type:
|
error_put_type:
|
||||||
key_type_put(ktype);
|
key_type_put(index_key.type);
|
||||||
error:
|
error:
|
||||||
return key_ref;
|
return key_ref;
|
||||||
|
|
||||||
|
@ -895,7 +897,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||||
/* we found a matching key, so we're going to try to update it
|
/* we found a matching key, so we're going to try to update it
|
||||||
* - we can drop the locks first as we have the key pinned
|
* - we can drop the locks first as we have the key pinned
|
||||||
*/
|
*/
|
||||||
__key_link_end(keyring, ktype, prealloc);
|
__key_link_end(keyring, &index_key, prealloc);
|
||||||
|
|
||||||
key_ref = __key_update(key_ref, &prep);
|
key_ref = __key_update(key_ref, &prep);
|
||||||
goto error_free_prep;
|
goto error_free_prep;
|
||||||
|
|
|
@ -538,8 +538,7 @@ EXPORT_SYMBOL(keyring_search);
|
||||||
* to the returned key reference.
|
* to the returned key reference.
|
||||||
*/
|
*/
|
||||||
key_ref_t __keyring_search_one(key_ref_t keyring_ref,
|
key_ref_t __keyring_search_one(key_ref_t keyring_ref,
|
||||||
const struct key_type *ktype,
|
const struct keyring_index_key *index_key,
|
||||||
const char *description,
|
|
||||||
key_perm_t perm)
|
key_perm_t perm)
|
||||||
{
|
{
|
||||||
struct keyring_list *klist;
|
struct keyring_list *klist;
|
||||||
|
@ -558,9 +557,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
|
||||||
smp_rmb();
|
smp_rmb();
|
||||||
for (loop = 0; loop < nkeys ; loop++) {
|
for (loop = 0; loop < nkeys ; loop++) {
|
||||||
key = rcu_dereference(klist->keys[loop]);
|
key = rcu_dereference(klist->keys[loop]);
|
||||||
if (key->type == ktype &&
|
if (key->type == index_key->type &&
|
||||||
(!key->type->match ||
|
(!key->type->match ||
|
||||||
key->type->match(key, description)) &&
|
key->type->match(key, index_key->description)) &&
|
||||||
key_permission(make_key_ref(key, possessed),
|
key_permission(make_key_ref(key, possessed),
|
||||||
perm) == 0 &&
|
perm) == 0 &&
|
||||||
!(key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
!(key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
||||||
|
@ -747,8 +746,8 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
|
||||||
/*
|
/*
|
||||||
* Preallocate memory so that a key can be linked into to a keyring.
|
* Preallocate memory so that a key can be linked into to a keyring.
|
||||||
*/
|
*/
|
||||||
int __key_link_begin(struct key *keyring, const struct key_type *type,
|
int __key_link_begin(struct key *keyring, const struct keyring_index_key *index_key,
|
||||||
const char *description, unsigned long *_prealloc)
|
unsigned long *_prealloc)
|
||||||
__acquires(&keyring->sem)
|
__acquires(&keyring->sem)
|
||||||
__acquires(&keyring_serialise_link_sem)
|
__acquires(&keyring_serialise_link_sem)
|
||||||
{
|
{
|
||||||
|
@ -759,7 +758,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
|
||||||
size_t size;
|
size_t size;
|
||||||
int loop, lru, ret;
|
int loop, lru, ret;
|
||||||
|
|
||||||
kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
|
kenter("%d,%s,%s,",
|
||||||
|
key_serial(keyring), index_key->type->name, index_key->description);
|
||||||
|
|
||||||
if (keyring->type != &key_type_keyring)
|
if (keyring->type != &key_type_keyring)
|
||||||
return -ENOTDIR;
|
return -ENOTDIR;
|
||||||
|
@ -772,7 +772,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
|
||||||
|
|
||||||
/* serialise link/link calls to prevent parallel calls causing a cycle
|
/* serialise link/link calls to prevent parallel calls causing a cycle
|
||||||
* when linking two keyring in opposite orders */
|
* when linking two keyring in opposite orders */
|
||||||
if (type == &key_type_keyring)
|
if (index_key->type == &key_type_keyring)
|
||||||
down_write(&keyring_serialise_link_sem);
|
down_write(&keyring_serialise_link_sem);
|
||||||
|
|
||||||
klist = rcu_dereference_locked_keyring(keyring);
|
klist = rcu_dereference_locked_keyring(keyring);
|
||||||
|
@ -784,8 +784,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
|
||||||
for (loop = klist->nkeys - 1; loop >= 0; loop--) {
|
for (loop = klist->nkeys - 1; loop >= 0; loop--) {
|
||||||
struct key *key = rcu_deref_link_locked(klist, loop,
|
struct key *key = rcu_deref_link_locked(klist, loop,
|
||||||
keyring);
|
keyring);
|
||||||
if (key->type == type &&
|
if (key->type == index_key->type &&
|
||||||
strcmp(key->description, description) == 0) {
|
strcmp(key->description, index_key->description) == 0) {
|
||||||
/* Found a match - we'll replace the link with
|
/* Found a match - we'll replace the link with
|
||||||
* one to the new key. We record the slot
|
* one to the new key. We record the slot
|
||||||
* position.
|
* position.
|
||||||
|
@ -865,7 +865,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
|
||||||
key_payload_reserve(keyring,
|
key_payload_reserve(keyring,
|
||||||
keyring->datalen - KEYQUOTA_LINK_BYTES);
|
keyring->datalen - KEYQUOTA_LINK_BYTES);
|
||||||
error_sem:
|
error_sem:
|
||||||
if (type == &key_type_keyring)
|
if (index_key->type == &key_type_keyring)
|
||||||
up_write(&keyring_serialise_link_sem);
|
up_write(&keyring_serialise_link_sem);
|
||||||
error_krsem:
|
error_krsem:
|
||||||
up_write(&keyring->sem);
|
up_write(&keyring->sem);
|
||||||
|
@ -957,16 +957,17 @@ void __key_link(struct key *keyring, struct key *key,
|
||||||
*
|
*
|
||||||
* Must be called with __key_link_begin() having being called.
|
* Must be called with __key_link_begin() having being called.
|
||||||
*/
|
*/
|
||||||
void __key_link_end(struct key *keyring, struct key_type *type,
|
void __key_link_end(struct key *keyring,
|
||||||
|
const struct keyring_index_key *index_key,
|
||||||
unsigned long prealloc)
|
unsigned long prealloc)
|
||||||
__releases(&keyring->sem)
|
__releases(&keyring->sem)
|
||||||
__releases(&keyring_serialise_link_sem)
|
__releases(&keyring_serialise_link_sem)
|
||||||
{
|
{
|
||||||
BUG_ON(type == NULL);
|
BUG_ON(index_key->type == NULL);
|
||||||
BUG_ON(type->name == NULL);
|
BUG_ON(index_key->type->name == NULL);
|
||||||
kenter("%d,%s,%lx", keyring->serial, type->name, prealloc);
|
kenter("%d,%s,%lx", keyring->serial, index_key->type->name, prealloc);
|
||||||
|
|
||||||
if (type == &key_type_keyring)
|
if (index_key->type == &key_type_keyring)
|
||||||
up_write(&keyring_serialise_link_sem);
|
up_write(&keyring_serialise_link_sem);
|
||||||
|
|
||||||
if (prealloc) {
|
if (prealloc) {
|
||||||
|
@ -1007,12 +1008,12 @@ int key_link(struct key *keyring, struct key *key)
|
||||||
key_check(keyring);
|
key_check(keyring);
|
||||||
key_check(key);
|
key_check(key);
|
||||||
|
|
||||||
ret = __key_link_begin(keyring, key->type, key->description, &prealloc);
|
ret = __key_link_begin(keyring, &key->index_key, &prealloc);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = __key_link_check_live_key(keyring, key);
|
ret = __key_link_check_live_key(keyring, key);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
__key_link(keyring, key, &prealloc);
|
__key_link(keyring, key, &prealloc);
|
||||||
__key_link_end(keyring, key->type, prealloc);
|
__key_link_end(keyring, &key->index_key, prealloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -352,6 +352,11 @@ static int construct_alloc_key(struct key_type *type,
|
||||||
struct key_user *user,
|
struct key_user *user,
|
||||||
struct key **_key)
|
struct key **_key)
|
||||||
{
|
{
|
||||||
|
const struct keyring_index_key index_key = {
|
||||||
|
.type = type,
|
||||||
|
.description = description,
|
||||||
|
.desc_len = strlen(description),
|
||||||
|
};
|
||||||
const struct cred *cred = current_cred();
|
const struct cred *cred = current_cred();
|
||||||
unsigned long prealloc;
|
unsigned long prealloc;
|
||||||
struct key *key;
|
struct key *key;
|
||||||
|
@ -379,8 +384,7 @@ static int construct_alloc_key(struct key_type *type,
|
||||||
set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
|
set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
|
||||||
|
|
||||||
if (dest_keyring) {
|
if (dest_keyring) {
|
||||||
ret = __key_link_begin(dest_keyring, type, description,
|
ret = __key_link_begin(dest_keyring, &index_key, &prealloc);
|
||||||
&prealloc);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto link_prealloc_failed;
|
goto link_prealloc_failed;
|
||||||
}
|
}
|
||||||
|
@ -400,7 +404,7 @@ static int construct_alloc_key(struct key_type *type,
|
||||||
|
|
||||||
mutex_unlock(&key_construction_mutex);
|
mutex_unlock(&key_construction_mutex);
|
||||||
if (dest_keyring)
|
if (dest_keyring)
|
||||||
__key_link_end(dest_keyring, type, prealloc);
|
__key_link_end(dest_keyring, &index_key, prealloc);
|
||||||
mutex_unlock(&user->cons_lock);
|
mutex_unlock(&user->cons_lock);
|
||||||
*_key = key;
|
*_key = key;
|
||||||
kleave(" = 0 [%d]", key_serial(key));
|
kleave(" = 0 [%d]", key_serial(key));
|
||||||
|
@ -416,7 +420,7 @@ static int construct_alloc_key(struct key_type *type,
|
||||||
ret = __key_link_check_live_key(dest_keyring, key);
|
ret = __key_link_check_live_key(dest_keyring, key);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
__key_link(dest_keyring, key, &prealloc);
|
__key_link(dest_keyring, key, &prealloc);
|
||||||
__key_link_end(dest_keyring, type, prealloc);
|
__key_link_end(dest_keyring, &index_key, prealloc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto link_check_failed;
|
goto link_check_failed;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue