aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index c70da6fb82ce..c1eac8084ade 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -398,7 +398,8 @@ static int __key_instantiate_and_link(struct key *key,
398 const void *data, 398 const void *data,
399 size_t datalen, 399 size_t datalen,
400 struct key *keyring, 400 struct key *keyring,
401 struct key *authkey) 401 struct key *authkey,
402 struct keyring_list **_prealloc)
402{ 403{
403 int ret, awaken; 404 int ret, awaken;
404 405
@@ -425,7 +426,7 @@ static int __key_instantiate_and_link(struct key *key,
425 426
426 /* and link it into the destination keyring */ 427 /* and link it into the destination keyring */
427 if (keyring) 428 if (keyring)
428 ret = __key_link(keyring, key); 429 __key_link(keyring, key, _prealloc);
429 430
430 /* disable the authorisation key */ 431 /* disable the authorisation key */
431 if (authkey) 432 if (authkey)
@@ -453,15 +454,21 @@ int key_instantiate_and_link(struct key *key,
453 struct key *keyring, 454 struct key *keyring,
454 struct key *authkey) 455 struct key *authkey)
455{ 456{
457 struct keyring_list *prealloc;
456 int ret; 458 int ret;
457 459
458 if (keyring) 460 if (keyring) {
459 down_write(&keyring->sem); 461 ret = __key_link_begin(keyring, key->type, key->description,
462 &prealloc);
463 if (ret < 0)
464 return ret;
465 }
460 466
461 ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey); 467 ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey,
468 &prealloc);
462 469
463 if (keyring) 470 if (keyring)
464 up_write(&keyring->sem); 471 __key_link_end(keyring, key->type, prealloc);
465 472
466 return ret; 473 return ret;
467 474
@@ -478,8 +485,9 @@ int key_negate_and_link(struct key *key,
478 struct key *keyring, 485 struct key *keyring,
479 struct key *authkey) 486 struct key *authkey)
480{ 487{
488 struct keyring_list *prealloc;
481 struct timespec now; 489 struct timespec now;
482 int ret, awaken; 490 int ret, awaken, link_ret = 0;
483 491
484 key_check(key); 492 key_check(key);
485 key_check(keyring); 493 key_check(keyring);
@@ -488,7 +496,8 @@ int key_negate_and_link(struct key *key,
488 ret = -EBUSY; 496 ret = -EBUSY;
489 497
490 if (keyring) 498 if (keyring)
491 down_write(&keyring->sem); 499 link_ret = __key_link_begin(keyring, key->type,
500 key->description, &prealloc);
492 501
493 mutex_lock(&key_construction_mutex); 502 mutex_lock(&key_construction_mutex);
494 503
@@ -508,8 +517,8 @@ int key_negate_and_link(struct key *key,
508 ret = 0; 517 ret = 0;
509 518
510 /* and link it into the destination keyring */ 519 /* and link it into the destination keyring */
511 if (keyring) 520 if (keyring && link_ret == 0)
512 ret = __key_link(keyring, key); 521 __key_link(keyring, key, &prealloc);
513 522
514 /* disable the authorisation key */ 523 /* disable the authorisation key */
515 if (authkey) 524 if (authkey)
@@ -519,13 +528,13 @@ int key_negate_and_link(struct key *key,
519 mutex_unlock(&key_construction_mutex); 528 mutex_unlock(&key_construction_mutex);
520 529
521 if (keyring) 530 if (keyring)
522 up_write(&keyring->sem); 531 __key_link_end(keyring, key->type, prealloc);
523 532
524 /* wake up anyone waiting for a key to be constructed */ 533 /* wake up anyone waiting for a key to be constructed */
525 if (awaken) 534 if (awaken)
526 wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); 535 wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
527 536
528 return ret; 537 return ret == 0 ? link_ret : ret;
529 538
530} /* end key_negate_and_link() */ 539} /* end key_negate_and_link() */
531 540
@@ -749,6 +758,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
749 key_perm_t perm, 758 key_perm_t perm,
750 unsigned long flags) 759 unsigned long flags)
751{ 760{
761 struct keyring_list *prealloc;
752 const struct cred *cred = current_cred(); 762 const struct cred *cred = current_cred();
753 struct key_type *ktype; 763 struct key_type *ktype;
754 struct key *keyring, *key = NULL; 764 struct key *keyring, *key = NULL;
@@ -775,7 +785,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
775 if (keyring->type != &key_type_keyring) 785 if (keyring->type != &key_type_keyring)
776 goto error_2; 786 goto error_2;
777 787
778 down_write(&keyring->sem); 788 ret = __key_link_begin(keyring, ktype, description, &prealloc);
789 if (ret < 0)
790 goto error_2;
779 791
780 /* if we're going to allocate a new key, we're going to have 792 /* if we're going to allocate a new key, we're going to have
781 * to modify the keyring */ 793 * to modify the keyring */
@@ -817,7 +829,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
817 } 829 }
818 830
819 /* instantiate it and link it into the target keyring */ 831 /* instantiate it and link it into the target keyring */
820 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL); 832 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL,
833 &prealloc);
821 if (ret < 0) { 834 if (ret < 0) {
822 key_put(key); 835 key_put(key);
823 key_ref = ERR_PTR(ret); 836 key_ref = ERR_PTR(ret);
@@ -827,7 +840,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
827 key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); 840 key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
828 841
829 error_3: 842 error_3:
830 up_write(&keyring->sem); 843 __key_link_end(keyring, ktype, prealloc);
831 error_2: 844 error_2:
832 key_type_put(ktype); 845 key_type_put(ktype);
833 error: 846 error:
@@ -837,7 +850,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
837 /* we found a matching key, so we're going to try to update it 850 /* we found a matching key, so we're going to try to update it
838 * - we can drop the locks first as we have the key pinned 851 * - we can drop the locks first as we have the key pinned
839 */ 852 */
840 up_write(&keyring->sem); 853 __key_link_end(keyring, ktype, prealloc);
841 key_type_put(ktype); 854 key_type_put(ktype);
842 855
843 key_ref = __key_update(key_ref, payload, plen); 856 key_ref = __key_update(key_ref, payload, plen);