aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2010-04-30 09:32:39 -0400
committerJames Morris <jmorris@namei.org>2010-05-06 08:25:02 -0400
commitf70e2e06196ad4c1c762037da2f75354f6c16b81 (patch)
tree9632a1e655efb684c87f8c7be6d091fbb1a430e7 /security
parent043b4d40f53131c5f72eca2a46555fe35328a930 (diff)
KEYS: Do preallocation for __key_link()
Do preallocation for __key_link() so that the various callers in request_key.c can deal with any errors from this source before attempting to construct a key. This allows them to assume that the actual linkage step is guaranteed to be successful. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/keys/internal.h11
-rw-r--r--security/keys/key.c45
-rw-r--r--security/keys/keyring.c242
-rw-r--r--security/keys/request_key.c47
4 files changed, 215 insertions, 130 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 24ba0307b7a..5d4402a1161 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -87,7 +87,16 @@ extern wait_queue_head_t request_key_conswq;
87extern struct key_type *key_type_lookup(const char *type); 87extern struct key_type *key_type_lookup(const char *type);
88extern void key_type_put(struct key_type *ktype); 88extern void key_type_put(struct key_type *ktype);
89 89
90extern int __key_link(struct key *keyring, struct key *key); 90extern int __key_link_begin(struct key *keyring,
91 const struct key_type *type,
92 const char *description,
93 struct keyring_list **_prealloc);
94extern int __key_link_check_live_key(struct key *keyring, struct key *key);
95extern void __key_link(struct key *keyring, struct key *key,
96 struct keyring_list **_prealloc);
97extern void __key_link_end(struct key *keyring,
98 struct key_type *type,
99 struct keyring_list *prealloc);
91 100
92extern key_ref_t __keyring_search_one(key_ref_t keyring_ref, 101extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
93 const struct key_type *type, 102 const struct key_type *type,
diff --git a/security/keys/key.c b/security/keys/key.c
index c70da6fb82c..c1eac8084ad 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);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 3f425a65906..ef03a82a013 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -660,20 +660,6 @@ cycle_detected:
660 660
661} /* end keyring_detect_cycle() */ 661} /* end keyring_detect_cycle() */
662 662
663/*****************************************************************************/
664/*
665 * dispose of a keyring list after the RCU grace period
666 */
667static void keyring_link_rcu_disposal(struct rcu_head *rcu)
668{
669 struct keyring_list *klist =
670 container_of(rcu, struct keyring_list, rcu);
671
672 kfree(klist);
673
674} /* end keyring_link_rcu_disposal() */
675
676/*****************************************************************************/
677/* 663/*
678 * dispose of a keyring list after the RCU grace period, freeing the unlinked 664 * dispose of a keyring list after the RCU grace period, freeing the unlinked
679 * key 665 * key
@@ -683,56 +669,51 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
683 struct keyring_list *klist = 669 struct keyring_list *klist =
684 container_of(rcu, struct keyring_list, rcu); 670 container_of(rcu, struct keyring_list, rcu);
685 671
686 key_put(klist->keys[klist->delkey]); 672 if (klist->delkey != USHORT_MAX)
673 key_put(klist->keys[klist->delkey]);
687 kfree(klist); 674 kfree(klist);
675}
688 676
689} /* end keyring_unlink_rcu_disposal() */
690
691/*****************************************************************************/
692/* 677/*
693 * link a key into to a keyring 678 * preallocate memory so that a key can be linked into to a keyring
694 * - must be called with the keyring's semaphore write-locked
695 * - discard already extant link to matching key if there is one
696 */ 679 */
697int __key_link(struct key *keyring, struct key *key) 680int __key_link_begin(struct key *keyring, const struct key_type *type,
681 const char *description,
682 struct keyring_list **_prealloc)
683 __acquires(&keyring->sem)
698{ 684{
699 struct keyring_list *klist, *nklist; 685 struct keyring_list *klist, *nklist;
700 unsigned max; 686 unsigned max;
701 size_t size; 687 size_t size;
702 int loop, ret; 688 int loop, ret;
703 689
704 ret = -EKEYREVOKED; 690 kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
705 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
706 goto error;
707 691
708 ret = -ENOTDIR;
709 if (keyring->type != &key_type_keyring) 692 if (keyring->type != &key_type_keyring)
710 goto error; 693 return -ENOTDIR;
694
695 down_write(&keyring->sem);
696
697 ret = -EKEYREVOKED;
698 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
699 goto error_krsem;
711 700
712 /* do some special keyring->keyring link checks */ 701 /* serialise link/link calls to prevent parallel calls causing a cycle
713 if (key->type == &key_type_keyring) { 702 * when linking two keyring in opposite orders */
714 /* serialise link/link calls to prevent parallel calls causing 703 if (type == &key_type_keyring)
715 * a cycle when applied to two keyring in opposite orders */
716 down_write(&keyring_serialise_link_sem); 704 down_write(&keyring_serialise_link_sem);
717 705
718 /* check that we aren't going to create a cycle adding one 706 klist = rcu_dereference_locked_keyring(keyring);
719 * keyring to another */
720 ret = keyring_detect_cycle(keyring, key);
721 if (ret < 0)
722 goto error2;
723 }
724 707
725 /* see if there's a matching key we can displace */ 708 /* see if there's a matching key we can displace */
726 klist = rcu_dereference_locked_keyring(keyring);
727 if (klist && klist->nkeys > 0) { 709 if (klist && klist->nkeys > 0) {
728 struct key_type *type = key->type;
729
730 for (loop = klist->nkeys - 1; loop >= 0; loop--) { 710 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
731 if (klist->keys[loop]->type == type && 711 if (klist->keys[loop]->type == type &&
732 strcmp(klist->keys[loop]->description, 712 strcmp(klist->keys[loop]->description,
733 key->description) == 0 713 description) == 0
734 ) { 714 ) {
735 /* found a match - replace with new key */ 715 /* found a match - we'll replace this one with
716 * the new key */
736 size = sizeof(struct key *) * klist->maxkeys; 717 size = sizeof(struct key *) * klist->maxkeys;
737 size += sizeof(*klist); 718 size += sizeof(*klist);
738 BUG_ON(size > PAGE_SIZE); 719 BUG_ON(size > PAGE_SIZE);
@@ -740,22 +721,10 @@ int __key_link(struct key *keyring, struct key *key)
740 ret = -ENOMEM; 721 ret = -ENOMEM;
741 nklist = kmemdup(klist, size, GFP_KERNEL); 722 nklist = kmemdup(klist, size, GFP_KERNEL);
742 if (!nklist) 723 if (!nklist)
743 goto error2; 724 goto error_sem;
744
745 /* replace matched key */
746 atomic_inc(&key->usage);
747 nklist->keys[loop] = key;
748
749 rcu_assign_pointer(
750 keyring->payload.subscriptions,
751 nklist);
752
753 /* dispose of the old keyring list and the
754 * displaced key */
755 klist->delkey = loop;
756 call_rcu(&klist->rcu,
757 keyring_unlink_rcu_disposal);
758 725
726 /* note replacement slot */
727 klist->delkey = nklist->delkey = loop;
759 goto done; 728 goto done;
760 } 729 }
761 } 730 }
@@ -765,16 +734,11 @@ int __key_link(struct key *keyring, struct key *key)
765 ret = key_payload_reserve(keyring, 734 ret = key_payload_reserve(keyring,
766 keyring->datalen + KEYQUOTA_LINK_BYTES); 735 keyring->datalen + KEYQUOTA_LINK_BYTES);
767 if (ret < 0) 736 if (ret < 0)
768 goto error2; 737 goto error_sem;
769 738
770 if (klist && klist->nkeys < klist->maxkeys) { 739 if (klist && klist->nkeys < klist->maxkeys) {
771 /* there's sufficient slack space to add directly */ 740 /* there's sufficient slack space to append directly */
772 atomic_inc(&key->usage); 741 nklist = NULL;
773
774 klist->keys[klist->nkeys] = key;
775 smp_wmb();
776 klist->nkeys++;
777 smp_wmb();
778 } else { 742 } else {
779 /* grow the key list */ 743 /* grow the key list */
780 max = 4; 744 max = 4;
@@ -782,71 +746,155 @@ int __key_link(struct key *keyring, struct key *key)
782 max += klist->maxkeys; 746 max += klist->maxkeys;
783 747
784 ret = -ENFILE; 748 ret = -ENFILE;
785 if (max > 65535) 749 if (max > USHORT_MAX - 1)
786 goto error3; 750 goto error_quota;
787 size = sizeof(*klist) + sizeof(struct key *) * max; 751 size = sizeof(*klist) + sizeof(struct key *) * max;
788 if (size > PAGE_SIZE) 752 if (size > PAGE_SIZE)
789 goto error3; 753 goto error_quota;
790 754
791 ret = -ENOMEM; 755 ret = -ENOMEM;
792 nklist = kmalloc(size, GFP_KERNEL); 756 nklist = kmalloc(size, GFP_KERNEL);
793 if (!nklist) 757 if (!nklist)
794 goto error3; 758 goto error_quota;
795 nklist->maxkeys = max;
796 nklist->nkeys = 0;
797 759
760 nklist->maxkeys = max;
798 if (klist) { 761 if (klist) {
799 nklist->nkeys = klist->nkeys; 762 memcpy(nklist->keys, klist->keys,
800 memcpy(nklist->keys,
801 klist->keys,
802 sizeof(struct key *) * klist->nkeys); 763 sizeof(struct key *) * klist->nkeys);
764 nklist->delkey = klist->nkeys;
765 nklist->nkeys = klist->nkeys + 1;
766 klist->delkey = USHORT_MAX;
767 } else {
768 nklist->nkeys = 1;
769 nklist->delkey = 0;
803 } 770 }
804 771
805 /* add the key into the new space */ 772 /* add the key into the new space */
806 atomic_inc(&key->usage); 773 nklist->keys[nklist->delkey] = NULL;
807 nklist->keys[nklist->nkeys++] = key;
808
809 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
810
811 /* dispose of the old keyring list */
812 if (klist)
813 call_rcu(&klist->rcu, keyring_link_rcu_disposal);
814 } 774 }
815 775
816done: 776done:
817 ret = 0; 777 *_prealloc = nklist;
818error2: 778 kleave(" = 0");
819 if (key->type == &key_type_keyring) 779 return 0;
820 up_write(&keyring_serialise_link_sem);
821error:
822 return ret;
823 780
824error3: 781error_quota:
825 /* undo the quota changes */ 782 /* undo the quota changes */
826 key_payload_reserve(keyring, 783 key_payload_reserve(keyring,
827 keyring->datalen - KEYQUOTA_LINK_BYTES); 784 keyring->datalen - KEYQUOTA_LINK_BYTES);
828 goto error2; 785error_sem:
786 if (type == &key_type_keyring)
787 up_write(&keyring_serialise_link_sem);
788error_krsem:
789 up_write(&keyring->sem);
790 kleave(" = %d", ret);
791 return ret;
792}
829 793
830} /* end __key_link() */ 794/*
795 * check already instantiated keys aren't going to be a problem
796 * - the caller must have called __key_link_begin()
797 * - don't need to call this for keys that were created since __key_link_begin()
798 * was called
799 */
800int __key_link_check_live_key(struct key *keyring, struct key *key)
801{
802 if (key->type == &key_type_keyring)
803 /* check that we aren't going to create a cycle by linking one
804 * keyring to another */
805 return keyring_detect_cycle(keyring, key);
806 return 0;
807}
808
809/*
810 * link a key into to a keyring
811 * - must be called with __key_link_begin() having being called
812 * - discard already extant link to matching key if there is one
813 */
814void __key_link(struct key *keyring, struct key *key,
815 struct keyring_list **_prealloc)
816{
817 struct keyring_list *klist, *nklist;
818
819 nklist = *_prealloc;
820 *_prealloc = NULL;
821
822 kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
823
824 klist = rcu_dereference_protected(keyring->payload.subscriptions,
825 rwsem_is_locked(&keyring->sem));
826
827 atomic_inc(&key->usage);
828
829 /* there's a matching key we can displace or an empty slot in a newly
830 * allocated list we can fill */
831 if (nklist) {
832 kdebug("replace %hu/%hu/%hu",
833 nklist->delkey, nklist->nkeys, nklist->maxkeys);
834
835 nklist->keys[nklist->delkey] = key;
836
837 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
838
839 /* dispose of the old keyring list and, if there was one, the
840 * displaced key */
841 if (klist) {
842 kdebug("dispose %hu/%hu/%hu",
843 klist->delkey, klist->nkeys, klist->maxkeys);
844 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
845 }
846 } else {
847 /* there's sufficient slack space to append directly */
848 klist->keys[klist->nkeys] = key;
849 smp_wmb();
850 klist->nkeys++;
851 }
852}
853
854/*
855 * finish linking a key into to a keyring
856 * - must be called with __key_link_begin() having being called
857 */
858void __key_link_end(struct key *keyring, struct key_type *type,
859 struct keyring_list *prealloc)
860 __releases(&keyring->sem)
861{
862 BUG_ON(type == NULL);
863 BUG_ON(type->name == NULL);
864 kenter("%d,%s,%p", keyring->serial, type->name, prealloc);
865
866 if (type == &key_type_keyring)
867 up_write(&keyring_serialise_link_sem);
868
869 if (prealloc) {
870 kfree(prealloc);
871 key_payload_reserve(keyring,
872 keyring->datalen - KEYQUOTA_LINK_BYTES);
873 }
874 up_write(&keyring->sem);
875}
831 876
832/*****************************************************************************/
833/* 877/*
834 * link a key to a keyring 878 * link a key to a keyring
835 */ 879 */
836int key_link(struct key *keyring, struct key *key) 880int key_link(struct key *keyring, struct key *key)
837{ 881{
882 struct keyring_list *prealloc;
838 int ret; 883 int ret;
839 884
840 key_check(keyring); 885 key_check(keyring);
841 key_check(key); 886 key_check(key);
842 887
843 down_write(&keyring->sem); 888 ret = __key_link_begin(keyring, key->type, key->description, &prealloc);
844 ret = __key_link(keyring, key); 889 if (ret == 0) {
845 up_write(&keyring->sem); 890 ret = __key_link_check_live_key(keyring, key);
891 if (ret == 0)
892 __key_link(keyring, key, &prealloc);
893 __key_link_end(keyring, key->type, prealloc);
894 }
846 895
847 return ret; 896 return ret;
848 897}
849} /* end key_link() */
850 898
851EXPORT_SYMBOL(key_link); 899EXPORT_SYMBOL(key_link);
852 900
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index ac49c8aacbf..f656e9c069e 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -299,6 +299,7 @@ static int construct_alloc_key(struct key_type *type,
299 struct key_user *user, 299 struct key_user *user,
300 struct key **_key) 300 struct key **_key)
301{ 301{
302 struct keyring_list *prealloc;
302 const struct cred *cred = current_cred(); 303 const struct cred *cred = current_cred();
303 struct key *key; 304 struct key *key;
304 key_ref_t key_ref; 305 key_ref_t key_ref;
@@ -306,6 +307,7 @@ static int construct_alloc_key(struct key_type *type,
306 307
307 kenter("%s,%s,,,", type->name, description); 308 kenter("%s,%s,,,", type->name, description);
308 309
310 *_key = NULL;
309 mutex_lock(&user->cons_lock); 311 mutex_lock(&user->cons_lock);
310 312
311 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred, 313 key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
@@ -315,8 +317,12 @@ static int construct_alloc_key(struct key_type *type,
315 317
316 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 318 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
317 319
318 if (dest_keyring) 320 if (dest_keyring) {
319 down_write(&dest_keyring->sem); 321 ret = __key_link_begin(dest_keyring, type, description,
322 &prealloc);
323 if (ret < 0)
324 goto link_prealloc_failed;
325 }
320 326
321 /* attach the key to the destination keyring under lock, but we do need 327 /* attach the key to the destination keyring under lock, but we do need
322 * to do another check just in case someone beat us to it whilst we 328 * to do another check just in case someone beat us to it whilst we
@@ -328,11 +334,11 @@ static int construct_alloc_key(struct key_type *type,
328 goto key_already_present; 334 goto key_already_present;
329 335
330 if (dest_keyring) 336 if (dest_keyring)
331 __key_link(dest_keyring, key); 337 __key_link(dest_keyring, key, &prealloc);
332 338
333 mutex_unlock(&key_construction_mutex); 339 mutex_unlock(&key_construction_mutex);
334 if (dest_keyring) 340 if (dest_keyring)
335 up_write(&dest_keyring->sem); 341 __key_link_end(dest_keyring, type, prealloc);
336 mutex_unlock(&user->cons_lock); 342 mutex_unlock(&user->cons_lock);
337 *_key = key; 343 *_key = key;
338 kleave(" = 0 [%d]", key_serial(key)); 344 kleave(" = 0 [%d]", key_serial(key));
@@ -341,27 +347,36 @@ static int construct_alloc_key(struct key_type *type,
341 /* the key is now present - we tell the caller that we found it by 347 /* the key is now present - we tell the caller that we found it by
342 * returning -EINPROGRESS */ 348 * returning -EINPROGRESS */
343key_already_present: 349key_already_present:
350 key_put(key);
344 mutex_unlock(&key_construction_mutex); 351 mutex_unlock(&key_construction_mutex);
345 ret = 0; 352 key = key_ref_to_ptr(key_ref);
346 if (dest_keyring) { 353 if (dest_keyring) {
347 ret = __key_link(dest_keyring, key_ref_to_ptr(key_ref)); 354 ret = __key_link_check_live_key(dest_keyring, key);
348 up_write(&dest_keyring->sem); 355 if (ret == 0)
356 __key_link(dest_keyring, key, &prealloc);
357 __key_link_end(dest_keyring, type, prealloc);
358 if (ret < 0)
359 goto link_check_failed;
349 } 360 }
350 mutex_unlock(&user->cons_lock); 361 mutex_unlock(&user->cons_lock);
351 key_put(key); 362 *_key = key;
352 if (ret < 0) {
353 key_ref_put(key_ref);
354 *_key = NULL;
355 kleave(" = %d [link]", ret);
356 return ret;
357 }
358 *_key = key = key_ref_to_ptr(key_ref);
359 kleave(" = -EINPROGRESS [%d]", key_serial(key)); 363 kleave(" = -EINPROGRESS [%d]", key_serial(key));
360 return -EINPROGRESS; 364 return -EINPROGRESS;
361 365
366link_check_failed:
367 mutex_unlock(&user->cons_lock);
368 key_put(key);
369 kleave(" = %d [linkcheck]", ret);
370 return ret;
371
372link_prealloc_failed:
373 up_write(&dest_keyring->sem);
374 mutex_unlock(&user->cons_lock);
375 kleave(" = %d [prelink]", ret);
376 return ret;
377
362alloc_failed: 378alloc_failed:
363 mutex_unlock(&user->cons_lock); 379 mutex_unlock(&user->cons_lock);
364 *_key = NULL;
365 kleave(" = %ld", PTR_ERR(key)); 380 kleave(" = %ld", PTR_ERR(key));
366 return PTR_ERR(key); 381 return PTR_ERR(key);
367} 382}