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.c114
1 files changed, 82 insertions, 32 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index a30e92734905..a15c9da8f971 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -405,8 +405,7 @@ EXPORT_SYMBOL(key_payload_reserve);
405 * key_construction_mutex. 405 * key_construction_mutex.
406 */ 406 */
407static int __key_instantiate_and_link(struct key *key, 407static int __key_instantiate_and_link(struct key *key,
408 const void *data, 408 struct key_preparsed_payload *prep,
409 size_t datalen,
410 struct key *keyring, 409 struct key *keyring,
411 struct key *authkey, 410 struct key *authkey,
412 unsigned long *_prealloc) 411 unsigned long *_prealloc)
@@ -424,7 +423,7 @@ static int __key_instantiate_and_link(struct key *key,
424 /* can't instantiate twice */ 423 /* can't instantiate twice */
425 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 424 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
426 /* instantiate the key */ 425 /* instantiate the key */
427 ret = key->type->instantiate(key, data, datalen); 426 ret = key->type->instantiate(key, prep);
428 427
429 if (ret == 0) { 428 if (ret == 0) {
430 /* mark the key as being instantiated */ 429 /* mark the key as being instantiated */
@@ -475,22 +474,37 @@ int key_instantiate_and_link(struct key *key,
475 struct key *keyring, 474 struct key *keyring,
476 struct key *authkey) 475 struct key *authkey)
477{ 476{
477 struct key_preparsed_payload prep;
478 unsigned long prealloc; 478 unsigned long prealloc;
479 int ret; 479 int ret;
480 480
481 memset(&prep, 0, sizeof(prep));
482 prep.data = data;
483 prep.datalen = datalen;
484 prep.quotalen = key->type->def_datalen;
485 if (key->type->preparse) {
486 ret = key->type->preparse(&prep);
487 if (ret < 0)
488 goto error;
489 }
490
481 if (keyring) { 491 if (keyring) {
482 ret = __key_link_begin(keyring, key->type, key->description, 492 ret = __key_link_begin(keyring, key->type, key->description,
483 &prealloc); 493 &prealloc);
484 if (ret < 0) 494 if (ret < 0)
485 return ret; 495 goto error_free_preparse;
486 } 496 }
487 497
488 ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey, 498 ret = __key_instantiate_and_link(key, &prep, keyring, authkey,
489 &prealloc); 499 &prealloc);
490 500
491 if (keyring) 501 if (keyring)
492 __key_link_end(keyring, key->type, prealloc); 502 __key_link_end(keyring, key->type, prealloc);
493 503
504error_free_preparse:
505 if (key->type->preparse)
506 key->type->free_preparse(&prep);
507error:
494 return ret; 508 return ret;
495} 509}
496 510
@@ -699,7 +713,7 @@ void key_type_put(struct key_type *ktype)
699 * if we get an error. 713 * if we get an error.
700 */ 714 */
701static inline key_ref_t __key_update(key_ref_t key_ref, 715static inline key_ref_t __key_update(key_ref_t key_ref,
702 const void *payload, size_t plen) 716 struct key_preparsed_payload *prep)
703{ 717{
704 struct key *key = key_ref_to_ptr(key_ref); 718 struct key *key = key_ref_to_ptr(key_ref);
705 int ret; 719 int ret;
@@ -715,7 +729,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
715 729
716 down_write(&key->sem); 730 down_write(&key->sem);
717 731
718 ret = key->type->update(key, payload, plen); 732 ret = key->type->update(key, prep);
719 if (ret == 0) 733 if (ret == 0)
720 /* updating a negative key instantiates it */ 734 /* updating a negative key instantiates it */
721 clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 735 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -767,6 +781,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
767 unsigned long flags) 781 unsigned long flags)
768{ 782{
769 unsigned long prealloc; 783 unsigned long prealloc;
784 struct key_preparsed_payload prep;
770 const struct cred *cred = current_cred(); 785 const struct cred *cred = current_cred();
771 struct key_type *ktype; 786 struct key_type *ktype;
772 struct key *keyring, *key = NULL; 787 struct key *keyring, *key = NULL;
@@ -782,8 +797,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
782 } 797 }
783 798
784 key_ref = ERR_PTR(-EINVAL); 799 key_ref = ERR_PTR(-EINVAL);
785 if (!ktype->match || !ktype->instantiate) 800 if (!ktype->match || !ktype->instantiate ||
786 goto error_2; 801 (!description && !ktype->preparse))
802 goto error_put_type;
787 803
788 keyring = key_ref_to_ptr(keyring_ref); 804 keyring = key_ref_to_ptr(keyring_ref);
789 805
@@ -791,18 +807,37 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
791 807
792 key_ref = ERR_PTR(-ENOTDIR); 808 key_ref = ERR_PTR(-ENOTDIR);
793 if (keyring->type != &key_type_keyring) 809 if (keyring->type != &key_type_keyring)
794 goto error_2; 810 goto error_put_type;
811
812 memset(&prep, 0, sizeof(prep));
813 prep.data = payload;
814 prep.datalen = plen;
815 prep.quotalen = ktype->def_datalen;
816 if (ktype->preparse) {
817 ret = ktype->preparse(&prep);
818 if (ret < 0) {
819 key_ref = ERR_PTR(ret);
820 goto error_put_type;
821 }
822 if (!description)
823 description = prep.description;
824 key_ref = ERR_PTR(-EINVAL);
825 if (!description)
826 goto error_free_prep;
827 }
795 828
796 ret = __key_link_begin(keyring, ktype, description, &prealloc); 829 ret = __key_link_begin(keyring, ktype, description, &prealloc);
797 if (ret < 0) 830 if (ret < 0) {
798 goto error_2; 831 key_ref = ERR_PTR(ret);
832 goto error_free_prep;
833 }
799 834
800 /* if we're going to allocate a new key, we're going to have 835 /* if we're going to allocate a new key, we're going to have
801 * to modify the keyring */ 836 * to modify the keyring */
802 ret = key_permission(keyring_ref, KEY_WRITE); 837 ret = key_permission(keyring_ref, KEY_WRITE);
803 if (ret < 0) { 838 if (ret < 0) {
804 key_ref = ERR_PTR(ret); 839 key_ref = ERR_PTR(ret);
805 goto error_3; 840 goto error_link_end;
806 } 841 }
807 842
808 /* if it's possible to update this type of key, search for an existing 843 /* if it's possible to update this type of key, search for an existing
@@ -833,25 +868,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
833 perm, flags); 868 perm, flags);
834 if (IS_ERR(key)) { 869 if (IS_ERR(key)) {
835 key_ref = ERR_CAST(key); 870 key_ref = ERR_CAST(key);
836 goto error_3; 871 goto error_link_end;
837 } 872 }
838 873
839 /* instantiate it and link it into the target keyring */ 874 /* instantiate it and link it into the target keyring */
840 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL, 875 ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc);
841 &prealloc);
842 if (ret < 0) { 876 if (ret < 0) {
843 key_put(key); 877 key_put(key);
844 key_ref = ERR_PTR(ret); 878 key_ref = ERR_PTR(ret);
845 goto error_3; 879 goto error_link_end;
846 } 880 }
847 881
848 key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); 882 key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
849 883
850 error_3: 884error_link_end:
851 __key_link_end(keyring, ktype, prealloc); 885 __key_link_end(keyring, ktype, prealloc);
852 error_2: 886error_free_prep:
887 if (ktype->preparse)
888 ktype->free_preparse(&prep);
889error_put_type:
853 key_type_put(ktype); 890 key_type_put(ktype);
854 error: 891error:
855 return key_ref; 892 return key_ref;
856 893
857 found_matching_key: 894 found_matching_key:
@@ -859,10 +896,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
859 * - we can drop the locks first as we have the key pinned 896 * - we can drop the locks first as we have the key pinned
860 */ 897 */
861 __key_link_end(keyring, ktype, prealloc); 898 __key_link_end(keyring, ktype, prealloc);
862 key_type_put(ktype);
863 899
864 key_ref = __key_update(key_ref, payload, plen); 900 key_ref = __key_update(key_ref, &prep);
865 goto error; 901 goto error_free_prep;
866} 902}
867EXPORT_SYMBOL(key_create_or_update); 903EXPORT_SYMBOL(key_create_or_update);
868 904
@@ -881,6 +917,7 @@ EXPORT_SYMBOL(key_create_or_update);
881 */ 917 */
882int key_update(key_ref_t key_ref, const void *payload, size_t plen) 918int key_update(key_ref_t key_ref, const void *payload, size_t plen)
883{ 919{
920 struct key_preparsed_payload prep;
884 struct key *key = key_ref_to_ptr(key_ref); 921 struct key *key = key_ref_to_ptr(key_ref);
885 int ret; 922 int ret;
886 923
@@ -893,18 +930,31 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
893 930
894 /* attempt to update it if supported */ 931 /* attempt to update it if supported */
895 ret = -EOPNOTSUPP; 932 ret = -EOPNOTSUPP;
896 if (key->type->update) { 933 if (!key->type->update)
897 down_write(&key->sem); 934 goto error;
898
899 ret = key->type->update(key, payload, plen);
900 if (ret == 0)
901 /* updating a negative key instantiates it */
902 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
903 935
904 up_write(&key->sem); 936 memset(&prep, 0, sizeof(prep));
937 prep.data = payload;
938 prep.datalen = plen;
939 prep.quotalen = key->type->def_datalen;
940 if (key->type->preparse) {
941 ret = key->type->preparse(&prep);
942 if (ret < 0)
943 goto error;
905 } 944 }
906 945
907 error: 946 down_write(&key->sem);
947
948 ret = key->type->update(key, &prep);
949 if (ret == 0)
950 /* updating a negative key instantiates it */
951 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
952
953 up_write(&key->sem);
954
955 if (key->type->preparse)
956 key->type->free_preparse(&prep);
957error:
908 return ret; 958 return ret;
909} 959}
910EXPORT_SYMBOL(key_update); 960EXPORT_SYMBOL(key_update);