]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - security/keys/key.c
Merge tag 'drm-misc-next-fixes-2019-12-12' of git://anongit.freedesktop.org/drm/drm...
[linux.git] / security / keys / key.c
index 9a6108aefae929341e4bb82721bf47e56679c34a..764f4c57913e95ee5836e523079f7bdb30f6a695 100644 (file)
@@ -281,11 +281,12 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL);
        if (!key->index_key.description)
                goto no_memory_3;
+       key->index_key.type = type;
+       key_set_index_key(&key->index_key);
 
        refcount_set(&key->usage, 1);
        init_rwsem(&key->sem);
        lockdep_set_class(&key->sem, &type->lock_class);
-       key->index_key.type = type;
        key->user = user;
        key->quotalen = quotalen;
        key->datalen = type->def_datalen;
@@ -312,6 +313,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
                goto security_error;
 
        /* publish the key by giving it a serial number */
+       refcount_inc(&key->domain_tag->usage);
        atomic_inc(&user->nkeys);
        key_alloc_serial(key);
 
@@ -455,7 +457,7 @@ static int __key_instantiate_and_link(struct key *key,
 
                        /* disable the authorisation key */
                        if (authkey)
-                               key_revoke(authkey);
+                               key_invalidate(authkey);
 
                        if (prep->expiry != TIME64_MAX) {
                                key->expiry = prep->expiry;
@@ -496,7 +498,7 @@ int key_instantiate_and_link(struct key *key,
                             struct key *authkey)
 {
        struct key_preparsed_payload prep;
-       struct assoc_array_edit *edit;
+       struct assoc_array_edit *edit = NULL;
        int ret;
 
        memset(&prep, 0, sizeof(prep));
@@ -511,10 +513,14 @@ int key_instantiate_and_link(struct key *key,
        }
 
        if (keyring) {
-               ret = __key_link_begin(keyring, &key->index_key, &edit);
+               ret = __key_link_lock(keyring, &key->index_key);
                if (ret < 0)
                        goto error;
 
+               ret = __key_link_begin(keyring, &key->index_key, &edit);
+               if (ret < 0)
+                       goto error_link_end;
+
                if (keyring->restrict_link && keyring->restrict_link->check) {
                        struct key_restriction *keyres = keyring->restrict_link;
 
@@ -566,7 +572,7 @@ int key_reject_and_link(struct key *key,
                        struct key *keyring,
                        struct key *authkey)
 {
-       struct assoc_array_edit *edit;
+       struct assoc_array_edit *edit = NULL;
        int ret, awaken, link_ret = 0;
 
        key_check(key);
@@ -579,7 +585,12 @@ int key_reject_and_link(struct key *key,
                if (keyring->restrict_link)
                        return -EPERM;
 
-               link_ret = __key_link_begin(keyring, &key->index_key, &edit);
+               link_ret = __key_link_lock(keyring, &key->index_key);
+               if (link_ret == 0) {
+                       link_ret = __key_link_begin(keyring, &key->index_key, &edit);
+                       if (link_ret < 0)
+                               __key_link_end(keyring, &key->index_key, edit);
+               }
        }
 
        mutex_lock(&key_construction_mutex);
@@ -603,7 +614,7 @@ int key_reject_and_link(struct key *key,
 
                /* disable the authorisation key */
                if (authkey)
-                       key_revoke(authkey);
+                       key_invalidate(authkey);
        }
 
        mutex_unlock(&key_construction_mutex);
@@ -806,7 +817,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                .description    = description,
        };
        struct key_preparsed_payload prep;
-       struct assoc_array_edit *edit;
+       struct assoc_array_edit *edit = NULL;
        const struct cred *cred = current_cred();
        struct key *keyring, *key = NULL;
        key_ref_t key_ref;
@@ -855,13 +866,20 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                        goto error_free_prep;
        }
        index_key.desc_len = strlen(index_key.description);
+       key_set_index_key(&index_key);
 
-       ret = __key_link_begin(keyring, &index_key, &edit);
+       ret = __key_link_lock(keyring, &index_key);
        if (ret < 0) {
                key_ref = ERR_PTR(ret);
                goto error_free_prep;
        }
 
+       ret = __key_link_begin(keyring, &index_key, &edit);
+       if (ret < 0) {
+               key_ref = ERR_PTR(ret);
+               goto error_link_end;
+       }
+
        if (restrict_link && restrict_link->check) {
                ret = restrict_link->check(keyring, index_key.type,
                                           &prep.payload, restrict_link->key);