|
@@ -242,8 +242,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- desclen = strlen(desc) + 1;
|
|
|
- quotalen = desclen + type->def_datalen;
|
|
|
+ desclen = strlen(desc);
|
|
|
+ quotalen = desclen + 1 + type->def_datalen;
|
|
|
|
|
|
/* get hold of the key tracking for this user */
|
|
|
user = key_user_lookup(uid);
|
|
@@ -277,7 +277,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
|
|
|
goto no_memory_2;
|
|
|
|
|
|
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)
|
|
|
goto no_memory_3;
|
|
|
}
|
|
@@ -285,7 +286,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
|
|
|
atomic_set(&key->usage, 1);
|
|
|
init_rwsem(&key->sem);
|
|
|
lockdep_set_class(&key->sem, &type->lock_class);
|
|
|
- key->type = type;
|
|
|
+ key->index_key.type = type;
|
|
|
key->user = user;
|
|
|
key->quotalen = quotalen;
|
|
|
key->datalen = type->def_datalen;
|
|
@@ -489,8 +490,7 @@ int key_instantiate_and_link(struct key *key,
|
|
|
}
|
|
|
|
|
|
if (keyring) {
|
|
|
- ret = __key_link_begin(keyring, key->type, key->description,
|
|
|
- &prealloc);
|
|
|
+ ret = __key_link_begin(keyring, &key->index_key, &prealloc);
|
|
|
if (ret < 0)
|
|
|
goto error_free_preparse;
|
|
|
}
|
|
@@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key,
|
|
|
&prealloc);
|
|
|
|
|
|
if (keyring)
|
|
|
- __key_link_end(keyring, key->type, prealloc);
|
|
|
+ __key_link_end(keyring, &key->index_key, prealloc);
|
|
|
|
|
|
error_free_preparse:
|
|
|
if (key->type->preparse)
|
|
@@ -548,8 +548,7 @@ int key_reject_and_link(struct key *key,
|
|
|
ret = -EBUSY;
|
|
|
|
|
|
if (keyring)
|
|
|
- link_ret = __key_link_begin(keyring, key->type,
|
|
|
- key->description, &prealloc);
|
|
|
+ link_ret = __key_link_begin(keyring, &key->index_key, &prealloc);
|
|
|
|
|
|
mutex_lock(&key_construction_mutex);
|
|
|
|
|
@@ -581,7 +580,7 @@ int key_reject_and_link(struct key *key,
|
|
|
mutex_unlock(&key_construction_mutex);
|
|
|
|
|
|
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 */
|
|
|
if (awaken)
|
|
@@ -780,25 +779,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
|
|
key_perm_t perm,
|
|
|
unsigned long flags)
|
|
|
{
|
|
|
- unsigned long prealloc;
|
|
|
+ struct keyring_index_key index_key = {
|
|
|
+ .description = description,
|
|
|
+ };
|
|
|
struct key_preparsed_payload prep;
|
|
|
const struct cred *cred = current_cred();
|
|
|
- struct key_type *ktype;
|
|
|
+ unsigned long prealloc;
|
|
|
struct key *keyring, *key = NULL;
|
|
|
key_ref_t key_ref;
|
|
|
int ret;
|
|
|
|
|
|
/* look up the key type to see if it's one of the registered kernel
|
|
|
* types */
|
|
|
- ktype = key_type_lookup(type);
|
|
|
- if (IS_ERR(ktype)) {
|
|
|
+ index_key.type = key_type_lookup(type);
|
|
|
+ if (IS_ERR(index_key.type)) {
|
|
|
key_ref = ERR_PTR(-ENODEV);
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
|
key_ref = ERR_PTR(-EINVAL);
|
|
|
- if (!ktype->match || !ktype->instantiate ||
|
|
|
- (!description && !ktype->preparse))
|
|
|
+ if (!index_key.type->match || !index_key.type->instantiate ||
|
|
|
+ (!index_key.description && !index_key.type->preparse))
|
|
|
goto error_put_type;
|
|
|
|
|
|
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));
|
|
|
prep.data = payload;
|
|
|
prep.datalen = plen;
|
|
|
- prep.quotalen = ktype->def_datalen;
|
|
|
- if (ktype->preparse) {
|
|
|
- ret = ktype->preparse(&prep);
|
|
|
+ prep.quotalen = index_key.type->def_datalen;
|
|
|
+ if (index_key.type->preparse) {
|
|
|
+ ret = index_key.type->preparse(&prep);
|
|
|
if (ret < 0) {
|
|
|
key_ref = ERR_PTR(ret);
|
|
|
goto error_put_type;
|
|
|
}
|
|
|
- if (!description)
|
|
|
- description = prep.description;
|
|
|
+ if (!index_key.description)
|
|
|
+ index_key.description = prep.description;
|
|
|
key_ref = ERR_PTR(-EINVAL);
|
|
|
- if (!description)
|
|
|
+ if (!index_key.description)
|
|
|
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) {
|
|
|
key_ref = ERR_PTR(ret);
|
|
|
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
|
|
|
* update that instead if possible
|
|
|
*/
|
|
|
- if (ktype->update) {
|
|
|
- key_ref = __keyring_search_one(keyring_ref, ktype, description,
|
|
|
- 0);
|
|
|
+ if (index_key.type->update) {
|
|
|
+ key_ref = __keyring_search_one(keyring_ref, &index_key, 0);
|
|
|
if (!IS_ERR(key_ref))
|
|
|
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_USR_VIEW;
|
|
|
|
|
|
- if (ktype->read)
|
|
|
+ if (index_key.type->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;
|
|
|
}
|
|
|
|
|
|
/* allocate a new key */
|
|
|
- key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred,
|
|
|
- perm, flags);
|
|
|
+ key = key_alloc(index_key.type, index_key.description,
|
|
|
+ cred->fsuid, cred->fsgid, cred, perm, flags);
|
|
|
if (IS_ERR(key)) {
|
|
|
key_ref = ERR_CAST(key);
|
|
|
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));
|
|
|
|
|
|
error_link_end:
|
|
|
- __key_link_end(keyring, ktype, prealloc);
|
|
|
+ __key_link_end(keyring, &index_key, prealloc);
|
|
|
error_free_prep:
|
|
|
- if (ktype->preparse)
|
|
|
- ktype->free_preparse(&prep);
|
|
|
+ if (index_key.type->preparse)
|
|
|
+ index_key.type->free_preparse(&prep);
|
|
|
error_put_type:
|
|
|
- key_type_put(ktype);
|
|
|
+ key_type_put(index_key.type);
|
|
|
error:
|
|
|
return key_ref;
|
|
|
|
|
@@ -895,7 +897,7 @@ error:
|
|
|
/* 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
|
|
|
*/
|
|
|
- __key_link_end(keyring, ktype, prealloc);
|
|
|
+ __key_link_end(keyring, &index_key, prealloc);
|
|
|
|
|
|
key_ref = __key_update(key_ref, &prep);
|
|
|
goto error_free_prep;
|