diff options
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 16 | ||||
-rw-r--r-- | security/keys/key.c | 114 | ||||
-rw-r--r-- | security/keys/keyctl.c | 18 | ||||
-rw-r--r-- | security/keys/keyring.c | 6 | ||||
-rw-r--r-- | security/keys/request_key_auth.c | 8 | ||||
-rw-r--r-- | security/keys/trusted.c | 16 | ||||
-rw-r--r-- | security/keys/user_defined.c | 14 |
7 files changed, 129 insertions, 63 deletions
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 2d1bb8af7696..9e1e005c7596 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
@@ -773,8 +773,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload, | |||
773 | * | 773 | * |
774 | * On success, return 0. Otherwise return errno. | 774 | * On success, return 0. Otherwise return errno. |
775 | */ | 775 | */ |
776 | static int encrypted_instantiate(struct key *key, const void *data, | 776 | static int encrypted_instantiate(struct key *key, |
777 | size_t datalen) | 777 | struct key_preparsed_payload *prep) |
778 | { | 778 | { |
779 | struct encrypted_key_payload *epayload = NULL; | 779 | struct encrypted_key_payload *epayload = NULL; |
780 | char *datablob = NULL; | 780 | char *datablob = NULL; |
@@ -782,16 +782,17 @@ static int encrypted_instantiate(struct key *key, const void *data, | |||
782 | char *master_desc = NULL; | 782 | char *master_desc = NULL; |
783 | char *decrypted_datalen = NULL; | 783 | char *decrypted_datalen = NULL; |
784 | char *hex_encoded_iv = NULL; | 784 | char *hex_encoded_iv = NULL; |
785 | size_t datalen = prep->datalen; | ||
785 | int ret; | 786 | int ret; |
786 | 787 | ||
787 | if (datalen <= 0 || datalen > 32767 || !data) | 788 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
788 | return -EINVAL; | 789 | return -EINVAL; |
789 | 790 | ||
790 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 791 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
791 | if (!datablob) | 792 | if (!datablob) |
792 | return -ENOMEM; | 793 | return -ENOMEM; |
793 | datablob[datalen] = 0; | 794 | datablob[datalen] = 0; |
794 | memcpy(datablob, data, datalen); | 795 | memcpy(datablob, prep->data, datalen); |
795 | ret = datablob_parse(datablob, &format, &master_desc, | 796 | ret = datablob_parse(datablob, &format, &master_desc, |
796 | &decrypted_datalen, &hex_encoded_iv); | 797 | &decrypted_datalen, &hex_encoded_iv); |
797 | if (ret < 0) | 798 | if (ret < 0) |
@@ -834,16 +835,17 @@ static void encrypted_rcu_free(struct rcu_head *rcu) | |||
834 | * | 835 | * |
835 | * On success, return 0. Otherwise return errno. | 836 | * On success, return 0. Otherwise return errno. |
836 | */ | 837 | */ |
837 | static int encrypted_update(struct key *key, const void *data, size_t datalen) | 838 | static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) |
838 | { | 839 | { |
839 | struct encrypted_key_payload *epayload = key->payload.data; | 840 | struct encrypted_key_payload *epayload = key->payload.data; |
840 | struct encrypted_key_payload *new_epayload; | 841 | struct encrypted_key_payload *new_epayload; |
841 | char *buf; | 842 | char *buf; |
842 | char *new_master_desc = NULL; | 843 | char *new_master_desc = NULL; |
843 | const char *format = NULL; | 844 | const char *format = NULL; |
845 | size_t datalen = prep->datalen; | ||
844 | int ret = 0; | 846 | int ret = 0; |
845 | 847 | ||
846 | if (datalen <= 0 || datalen > 32767 || !data) | 848 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
847 | return -EINVAL; | 849 | return -EINVAL; |
848 | 850 | ||
849 | buf = kmalloc(datalen + 1, GFP_KERNEL); | 851 | buf = kmalloc(datalen + 1, GFP_KERNEL); |
@@ -851,7 +853,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) | |||
851 | return -ENOMEM; | 853 | return -ENOMEM; |
852 | 854 | ||
853 | buf[datalen] = 0; | 855 | buf[datalen] = 0; |
854 | memcpy(buf, data, datalen); | 856 | memcpy(buf, prep->data, datalen); |
855 | ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); | 857 | ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); |
856 | if (ret < 0) | 858 | if (ret < 0) |
857 | goto out; | 859 | goto out; |
diff --git a/security/keys/key.c b/security/keys/key.c index 50d96d4e06f2..1d039af99f50 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -412,8 +412,7 @@ EXPORT_SYMBOL(key_payload_reserve); | |||
412 | * key_construction_mutex. | 412 | * key_construction_mutex. |
413 | */ | 413 | */ |
414 | static int __key_instantiate_and_link(struct key *key, | 414 | static int __key_instantiate_and_link(struct key *key, |
415 | const void *data, | 415 | struct key_preparsed_payload *prep, |
416 | size_t datalen, | ||
417 | struct key *keyring, | 416 | struct key *keyring, |
418 | struct key *authkey, | 417 | struct key *authkey, |
419 | unsigned long *_prealloc) | 418 | unsigned long *_prealloc) |
@@ -431,7 +430,7 @@ static int __key_instantiate_and_link(struct key *key, | |||
431 | /* can't instantiate twice */ | 430 | /* can't instantiate twice */ |
432 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { | 431 | if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { |
433 | /* instantiate the key */ | 432 | /* instantiate the key */ |
434 | ret = key->type->instantiate(key, data, datalen); | 433 | ret = key->type->instantiate(key, prep); |
435 | 434 | ||
436 | if (ret == 0) { | 435 | if (ret == 0) { |
437 | /* mark the key as being instantiated */ | 436 | /* mark the key as being instantiated */ |
@@ -482,22 +481,37 @@ int key_instantiate_and_link(struct key *key, | |||
482 | struct key *keyring, | 481 | struct key *keyring, |
483 | struct key *authkey) | 482 | struct key *authkey) |
484 | { | 483 | { |
484 | struct key_preparsed_payload prep; | ||
485 | unsigned long prealloc; | 485 | unsigned long prealloc; |
486 | int ret; | 486 | int ret; |
487 | 487 | ||
488 | memset(&prep, 0, sizeof(prep)); | ||
489 | prep.data = data; | ||
490 | prep.datalen = datalen; | ||
491 | prep.quotalen = key->type->def_datalen; | ||
492 | if (key->type->preparse) { | ||
493 | ret = key->type->preparse(&prep); | ||
494 | if (ret < 0) | ||
495 | goto error; | ||
496 | } | ||
497 | |||
488 | if (keyring) { | 498 | if (keyring) { |
489 | ret = __key_link_begin(keyring, key->type, key->description, | 499 | ret = __key_link_begin(keyring, key->type, key->description, |
490 | &prealloc); | 500 | &prealloc); |
491 | if (ret < 0) | 501 | if (ret < 0) |
492 | return ret; | 502 | goto error_free_preparse; |
493 | } | 503 | } |
494 | 504 | ||
495 | ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey, | 505 | ret = __key_instantiate_and_link(key, &prep, keyring, authkey, |
496 | &prealloc); | 506 | &prealloc); |
497 | 507 | ||
498 | if (keyring) | 508 | if (keyring) |
499 | __key_link_end(keyring, key->type, prealloc); | 509 | __key_link_end(keyring, key->type, prealloc); |
500 | 510 | ||
511 | error_free_preparse: | ||
512 | if (key->type->preparse) | ||
513 | key->type->free_preparse(&prep); | ||
514 | error: | ||
501 | return ret; | 515 | return ret; |
502 | } | 516 | } |
503 | 517 | ||
@@ -706,7 +720,7 @@ void key_type_put(struct key_type *ktype) | |||
706 | * if we get an error. | 720 | * if we get an error. |
707 | */ | 721 | */ |
708 | static inline key_ref_t __key_update(key_ref_t key_ref, | 722 | static inline key_ref_t __key_update(key_ref_t key_ref, |
709 | const void *payload, size_t plen) | 723 | struct key_preparsed_payload *prep) |
710 | { | 724 | { |
711 | struct key *key = key_ref_to_ptr(key_ref); | 725 | struct key *key = key_ref_to_ptr(key_ref); |
712 | int ret; | 726 | int ret; |
@@ -722,7 +736,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref, | |||
722 | 736 | ||
723 | down_write(&key->sem); | 737 | down_write(&key->sem); |
724 | 738 | ||
725 | ret = key->type->update(key, payload, plen); | 739 | ret = key->type->update(key, prep); |
726 | if (ret == 0) | 740 | if (ret == 0) |
727 | /* updating a negative key instantiates it */ | 741 | /* updating a negative key instantiates it */ |
728 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); | 742 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); |
@@ -774,6 +788,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
774 | unsigned long flags) | 788 | unsigned long flags) |
775 | { | 789 | { |
776 | unsigned long prealloc; | 790 | unsigned long prealloc; |
791 | struct key_preparsed_payload prep; | ||
777 | const struct cred *cred = current_cred(); | 792 | const struct cred *cred = current_cred(); |
778 | struct key_type *ktype; | 793 | struct key_type *ktype; |
779 | struct key *keyring, *key = NULL; | 794 | struct key *keyring, *key = NULL; |
@@ -789,8 +804,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
789 | } | 804 | } |
790 | 805 | ||
791 | key_ref = ERR_PTR(-EINVAL); | 806 | key_ref = ERR_PTR(-EINVAL); |
792 | if (!ktype->match || !ktype->instantiate) | 807 | if (!ktype->match || !ktype->instantiate || |
793 | goto error_2; | 808 | (!description && !ktype->preparse)) |
809 | goto error_put_type; | ||
794 | 810 | ||
795 | keyring = key_ref_to_ptr(keyring_ref); | 811 | keyring = key_ref_to_ptr(keyring_ref); |
796 | 812 | ||
@@ -798,18 +814,37 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
798 | 814 | ||
799 | key_ref = ERR_PTR(-ENOTDIR); | 815 | key_ref = ERR_PTR(-ENOTDIR); |
800 | if (keyring->type != &key_type_keyring) | 816 | if (keyring->type != &key_type_keyring) |
801 | goto error_2; | 817 | goto error_put_type; |
818 | |||
819 | memset(&prep, 0, sizeof(prep)); | ||
820 | prep.data = payload; | ||
821 | prep.datalen = plen; | ||
822 | prep.quotalen = ktype->def_datalen; | ||
823 | if (ktype->preparse) { | ||
824 | ret = ktype->preparse(&prep); | ||
825 | if (ret < 0) { | ||
826 | key_ref = ERR_PTR(ret); | ||
827 | goto error_put_type; | ||
828 | } | ||
829 | if (!description) | ||
830 | description = prep.description; | ||
831 | key_ref = ERR_PTR(-EINVAL); | ||
832 | if (!description) | ||
833 | goto error_free_prep; | ||
834 | } | ||
802 | 835 | ||
803 | ret = __key_link_begin(keyring, ktype, description, &prealloc); | 836 | ret = __key_link_begin(keyring, ktype, description, &prealloc); |
804 | if (ret < 0) | 837 | if (ret < 0) { |
805 | goto error_2; | 838 | key_ref = ERR_PTR(ret); |
839 | goto error_free_prep; | ||
840 | } | ||
806 | 841 | ||
807 | /* if we're going to allocate a new key, we're going to have | 842 | /* if we're going to allocate a new key, we're going to have |
808 | * to modify the keyring */ | 843 | * to modify the keyring */ |
809 | ret = key_permission(keyring_ref, KEY_WRITE); | 844 | ret = key_permission(keyring_ref, KEY_WRITE); |
810 | if (ret < 0) { | 845 | if (ret < 0) { |
811 | key_ref = ERR_PTR(ret); | 846 | key_ref = ERR_PTR(ret); |
812 | goto error_3; | 847 | goto error_link_end; |
813 | } | 848 | } |
814 | 849 | ||
815 | /* if it's possible to update this type of key, search for an existing | 850 | /* if it's possible to update this type of key, search for an existing |
@@ -840,25 +875,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
840 | perm, flags); | 875 | perm, flags); |
841 | if (IS_ERR(key)) { | 876 | if (IS_ERR(key)) { |
842 | key_ref = ERR_CAST(key); | 877 | key_ref = ERR_CAST(key); |
843 | goto error_3; | 878 | goto error_link_end; |
844 | } | 879 | } |
845 | 880 | ||
846 | /* instantiate it and link it into the target keyring */ | 881 | /* instantiate it and link it into the target keyring */ |
847 | ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL, | 882 | ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc); |
848 | &prealloc); | ||
849 | if (ret < 0) { | 883 | if (ret < 0) { |
850 | key_put(key); | 884 | key_put(key); |
851 | key_ref = ERR_PTR(ret); | 885 | key_ref = ERR_PTR(ret); |
852 | goto error_3; | 886 | goto error_link_end; |
853 | } | 887 | } |
854 | 888 | ||
855 | key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); | 889 | key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); |
856 | 890 | ||
857 | error_3: | 891 | error_link_end: |
858 | __key_link_end(keyring, ktype, prealloc); | 892 | __key_link_end(keyring, ktype, prealloc); |
859 | error_2: | 893 | error_free_prep: |
894 | if (ktype->preparse) | ||
895 | ktype->free_preparse(&prep); | ||
896 | error_put_type: | ||
860 | key_type_put(ktype); | 897 | key_type_put(ktype); |
861 | error: | 898 | error: |
862 | return key_ref; | 899 | return key_ref; |
863 | 900 | ||
864 | found_matching_key: | 901 | found_matching_key: |
@@ -866,10 +903,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
866 | * - we can drop the locks first as we have the key pinned | 903 | * - we can drop the locks first as we have the key pinned |
867 | */ | 904 | */ |
868 | __key_link_end(keyring, ktype, prealloc); | 905 | __key_link_end(keyring, ktype, prealloc); |
869 | key_type_put(ktype); | ||
870 | 906 | ||
871 | key_ref = __key_update(key_ref, payload, plen); | 907 | key_ref = __key_update(key_ref, &prep); |
872 | goto error; | 908 | goto error_free_prep; |
873 | } | 909 | } |
874 | EXPORT_SYMBOL(key_create_or_update); | 910 | EXPORT_SYMBOL(key_create_or_update); |
875 | 911 | ||
@@ -888,6 +924,7 @@ EXPORT_SYMBOL(key_create_or_update); | |||
888 | */ | 924 | */ |
889 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) | 925 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) |
890 | { | 926 | { |
927 | struct key_preparsed_payload prep; | ||
891 | struct key *key = key_ref_to_ptr(key_ref); | 928 | struct key *key = key_ref_to_ptr(key_ref); |
892 | int ret; | 929 | int ret; |
893 | 930 | ||
@@ -900,18 +937,31 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) | |||
900 | 937 | ||
901 | /* attempt to update it if supported */ | 938 | /* attempt to update it if supported */ |
902 | ret = -EOPNOTSUPP; | 939 | ret = -EOPNOTSUPP; |
903 | if (key->type->update) { | 940 | if (!key->type->update) |
904 | down_write(&key->sem); | 941 | goto error; |
905 | |||
906 | ret = key->type->update(key, payload, plen); | ||
907 | if (ret == 0) | ||
908 | /* updating a negative key instantiates it */ | ||
909 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); | ||
910 | 942 | ||
911 | up_write(&key->sem); | 943 | memset(&prep, 0, sizeof(prep)); |
944 | prep.data = payload; | ||
945 | prep.datalen = plen; | ||
946 | prep.quotalen = key->type->def_datalen; | ||
947 | if (key->type->preparse) { | ||
948 | ret = key->type->preparse(&prep); | ||
949 | if (ret < 0) | ||
950 | goto error; | ||
912 | } | 951 | } |
913 | 952 | ||
914 | error: | 953 | down_write(&key->sem); |
954 | |||
955 | ret = key->type->update(key, &prep); | ||
956 | if (ret == 0) | ||
957 | /* updating a negative key instantiates it */ | ||
958 | clear_bit(KEY_FLAG_NEGATIVE, &key->flags); | ||
959 | |||
960 | up_write(&key->sem); | ||
961 | |||
962 | if (key->type->preparse) | ||
963 | key->type->free_preparse(&prep); | ||
964 | error: | ||
915 | return ret; | 965 | return ret; |
916 | } | 966 | } |
917 | EXPORT_SYMBOL(key_update); | 967 | EXPORT_SYMBOL(key_update); |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 3364fbf46807..505d40be196c 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -46,6 +46,9 @@ static int key_get_type_from_user(char *type, | |||
46 | * Extract the description of a new key from userspace and either add it as a | 46 | * Extract the description of a new key from userspace and either add it as a |
47 | * new key to the specified keyring or update a matching key in that keyring. | 47 | * new key to the specified keyring or update a matching key in that keyring. |
48 | * | 48 | * |
49 | * If the description is NULL or an empty string, the key type is asked to | ||
50 | * generate one from the payload. | ||
51 | * | ||
49 | * The keyring must be writable so that we can attach the key to it. | 52 | * The keyring must be writable so that we can attach the key to it. |
50 | * | 53 | * |
51 | * If successful, the new key's serial number is returned, otherwise an error | 54 | * If successful, the new key's serial number is returned, otherwise an error |
@@ -72,10 +75,17 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, | |||
72 | if (ret < 0) | 75 | if (ret < 0) |
73 | goto error; | 76 | goto error; |
74 | 77 | ||
75 | description = strndup_user(_description, PAGE_SIZE); | 78 | description = NULL; |
76 | if (IS_ERR(description)) { | 79 | if (_description) { |
77 | ret = PTR_ERR(description); | 80 | description = strndup_user(_description, PAGE_SIZE); |
78 | goto error; | 81 | if (IS_ERR(description)) { |
82 | ret = PTR_ERR(description); | ||
83 | goto error; | ||
84 | } | ||
85 | if (!*description) { | ||
86 | kfree(description); | ||
87 | description = NULL; | ||
88 | } | ||
79 | } | 89 | } |
80 | 90 | ||
81 | /* pull the payload in if one was supplied */ | 91 | /* pull the payload in if one was supplied */ |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 81e7852d281d..f04d8cf81f3c 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -66,7 +66,7 @@ static inline unsigned keyring_hash(const char *desc) | |||
66 | * operations. | 66 | * operations. |
67 | */ | 67 | */ |
68 | static int keyring_instantiate(struct key *keyring, | 68 | static int keyring_instantiate(struct key *keyring, |
69 | const void *data, size_t datalen); | 69 | struct key_preparsed_payload *prep); |
70 | static int keyring_match(const struct key *keyring, const void *criterion); | 70 | static int keyring_match(const struct key *keyring, const void *criterion); |
71 | static void keyring_revoke(struct key *keyring); | 71 | static void keyring_revoke(struct key *keyring); |
72 | static void keyring_destroy(struct key *keyring); | 72 | static void keyring_destroy(struct key *keyring); |
@@ -121,12 +121,12 @@ static void keyring_publish_name(struct key *keyring) | |||
121 | * Returns 0 on success, -EINVAL if given any data. | 121 | * Returns 0 on success, -EINVAL if given any data. |
122 | */ | 122 | */ |
123 | static int keyring_instantiate(struct key *keyring, | 123 | static int keyring_instantiate(struct key *keyring, |
124 | const void *data, size_t datalen) | 124 | struct key_preparsed_payload *prep) |
125 | { | 125 | { |
126 | int ret; | 126 | int ret; |
127 | 127 | ||
128 | ret = -EINVAL; | 128 | ret = -EINVAL; |
129 | if (datalen == 0) { | 129 | if (prep->datalen == 0) { |
130 | /* make the keyring available by name if it has one */ | 130 | /* make the keyring available by name if it has one */ |
131 | keyring_publish_name(keyring); | 131 | keyring_publish_name(keyring); |
132 | ret = 0; | 132 | ret = 0; |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 60d4e3f5e4bb..85730d5a5a59 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -19,7 +19,8 @@ | |||
19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
20 | #include "internal.h" | 20 | #include "internal.h" |
21 | 21 | ||
22 | static int request_key_auth_instantiate(struct key *, const void *, size_t); | 22 | static int request_key_auth_instantiate(struct key *, |
23 | struct key_preparsed_payload *); | ||
23 | static void request_key_auth_describe(const struct key *, struct seq_file *); | 24 | static void request_key_auth_describe(const struct key *, struct seq_file *); |
24 | static void request_key_auth_revoke(struct key *); | 25 | static void request_key_auth_revoke(struct key *); |
25 | static void request_key_auth_destroy(struct key *); | 26 | static void request_key_auth_destroy(struct key *); |
@@ -42,10 +43,9 @@ struct key_type key_type_request_key_auth = { | |||
42 | * Instantiate a request-key authorisation key. | 43 | * Instantiate a request-key authorisation key. |
43 | */ | 44 | */ |
44 | static int request_key_auth_instantiate(struct key *key, | 45 | static int request_key_auth_instantiate(struct key *key, |
45 | const void *data, | 46 | struct key_preparsed_payload *prep) |
46 | size_t datalen) | ||
47 | { | 47 | { |
48 | key->payload.data = (struct request_key_auth *) data; | 48 | key->payload.data = (struct request_key_auth *)prep->data; |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 2d5d041f2049..42036c7a0856 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
@@ -927,22 +927,23 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key) | |||
927 | * | 927 | * |
928 | * On success, return 0. Otherwise return errno. | 928 | * On success, return 0. Otherwise return errno. |
929 | */ | 929 | */ |
930 | static int trusted_instantiate(struct key *key, const void *data, | 930 | static int trusted_instantiate(struct key *key, |
931 | size_t datalen) | 931 | struct key_preparsed_payload *prep) |
932 | { | 932 | { |
933 | struct trusted_key_payload *payload = NULL; | 933 | struct trusted_key_payload *payload = NULL; |
934 | struct trusted_key_options *options = NULL; | 934 | struct trusted_key_options *options = NULL; |
935 | size_t datalen = prep->datalen; | ||
935 | char *datablob; | 936 | char *datablob; |
936 | int ret = 0; | 937 | int ret = 0; |
937 | int key_cmd; | 938 | int key_cmd; |
938 | 939 | ||
939 | if (datalen <= 0 || datalen > 32767 || !data) | 940 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
940 | return -EINVAL; | 941 | return -EINVAL; |
941 | 942 | ||
942 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 943 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
943 | if (!datablob) | 944 | if (!datablob) |
944 | return -ENOMEM; | 945 | return -ENOMEM; |
945 | memcpy(datablob, data, datalen); | 946 | memcpy(datablob, prep->data, datalen); |
946 | datablob[datalen] = '\0'; | 947 | datablob[datalen] = '\0'; |
947 | 948 | ||
948 | options = trusted_options_alloc(); | 949 | options = trusted_options_alloc(); |
@@ -1011,17 +1012,18 @@ static void trusted_rcu_free(struct rcu_head *rcu) | |||
1011 | /* | 1012 | /* |
1012 | * trusted_update - reseal an existing key with new PCR values | 1013 | * trusted_update - reseal an existing key with new PCR values |
1013 | */ | 1014 | */ |
1014 | static int trusted_update(struct key *key, const void *data, size_t datalen) | 1015 | static int trusted_update(struct key *key, struct key_preparsed_payload *prep) |
1015 | { | 1016 | { |
1016 | struct trusted_key_payload *p = key->payload.data; | 1017 | struct trusted_key_payload *p = key->payload.data; |
1017 | struct trusted_key_payload *new_p; | 1018 | struct trusted_key_payload *new_p; |
1018 | struct trusted_key_options *new_o; | 1019 | struct trusted_key_options *new_o; |
1020 | size_t datalen = prep->datalen; | ||
1019 | char *datablob; | 1021 | char *datablob; |
1020 | int ret = 0; | 1022 | int ret = 0; |
1021 | 1023 | ||
1022 | if (!p->migratable) | 1024 | if (!p->migratable) |
1023 | return -EPERM; | 1025 | return -EPERM; |
1024 | if (datalen <= 0 || datalen > 32767 || !data) | 1026 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
1025 | return -EINVAL; | 1027 | return -EINVAL; |
1026 | 1028 | ||
1027 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 1029 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
@@ -1038,7 +1040,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen) | |||
1038 | goto out; | 1040 | goto out; |
1039 | } | 1041 | } |
1040 | 1042 | ||
1041 | memcpy(datablob, data, datalen); | 1043 | memcpy(datablob, prep->data, datalen); |
1042 | datablob[datalen] = '\0'; | 1044 | datablob[datalen] = '\0'; |
1043 | ret = datablob_parse(datablob, new_p, new_o); | 1045 | ret = datablob_parse(datablob, new_p, new_o); |
1044 | if (ret != Opt_update) { | 1046 | if (ret != Opt_update) { |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index c7660a25a3e4..55dc88939185 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c | |||
@@ -58,13 +58,14 @@ EXPORT_SYMBOL_GPL(key_type_logon); | |||
58 | /* | 58 | /* |
59 | * instantiate a user defined key | 59 | * instantiate a user defined key |
60 | */ | 60 | */ |
61 | int user_instantiate(struct key *key, const void *data, size_t datalen) | 61 | int user_instantiate(struct key *key, struct key_preparsed_payload *prep) |
62 | { | 62 | { |
63 | struct user_key_payload *upayload; | 63 | struct user_key_payload *upayload; |
64 | size_t datalen = prep->datalen; | ||
64 | int ret; | 65 | int ret; |
65 | 66 | ||
66 | ret = -EINVAL; | 67 | ret = -EINVAL; |
67 | if (datalen <= 0 || datalen > 32767 || !data) | 68 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
68 | goto error; | 69 | goto error; |
69 | 70 | ||
70 | ret = key_payload_reserve(key, datalen); | 71 | ret = key_payload_reserve(key, datalen); |
@@ -78,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen) | |||
78 | 79 | ||
79 | /* attach the data */ | 80 | /* attach the data */ |
80 | upayload->datalen = datalen; | 81 | upayload->datalen = datalen; |
81 | memcpy(upayload->data, data, datalen); | 82 | memcpy(upayload->data, prep->data, datalen); |
82 | rcu_assign_keypointer(key, upayload); | 83 | rcu_assign_keypointer(key, upayload); |
83 | ret = 0; | 84 | ret = 0; |
84 | 85 | ||
@@ -92,13 +93,14 @@ EXPORT_SYMBOL_GPL(user_instantiate); | |||
92 | * update a user defined key | 93 | * update a user defined key |
93 | * - the key's semaphore is write-locked | 94 | * - the key's semaphore is write-locked |
94 | */ | 95 | */ |
95 | int user_update(struct key *key, const void *data, size_t datalen) | 96 | int user_update(struct key *key, struct key_preparsed_payload *prep) |
96 | { | 97 | { |
97 | struct user_key_payload *upayload, *zap; | 98 | struct user_key_payload *upayload, *zap; |
99 | size_t datalen = prep->datalen; | ||
98 | int ret; | 100 | int ret; |
99 | 101 | ||
100 | ret = -EINVAL; | 102 | ret = -EINVAL; |
101 | if (datalen <= 0 || datalen > 32767 || !data) | 103 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
102 | goto error; | 104 | goto error; |
103 | 105 | ||
104 | /* construct a replacement payload */ | 106 | /* construct a replacement payload */ |
@@ -108,7 +110,7 @@ int user_update(struct key *key, const void *data, size_t datalen) | |||
108 | goto error; | 110 | goto error; |
109 | 111 | ||
110 | upayload->datalen = datalen; | 112 | upayload->datalen = datalen; |
111 | memcpy(upayload->data, data, datalen); | 113 | memcpy(upayload->data, prep->data, datalen); |
112 | 114 | ||
113 | /* check the quota and attach the new data */ | 115 | /* check the quota and attach the new data */ |
114 | zap = upayload; | 116 | zap = upayload; |