aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-09-13 08:06:29 -0400
committerDavid Howells <dhowells@redhat.com>2012-09-13 08:06:29 -0400
commitd4f65b5d2497b2fd9c45f06b71deb4ab084a5b66 (patch)
tree57128a75a755e2b4a6521408cc2eaf73c88e54aa /security
parenteeea3ac912207dcf759b95b2b4c36f96bce583bf (diff)
KEYS: Add payload preparsing opportunity prior to key instantiate or update
Give the key type the opportunity to preparse the payload prior to the instantiation and update routines being called. This is done with the provision of two new key type operations: int (*preparse)(struct key_preparsed_payload *prep); void (*free_preparse)(struct key_preparsed_payload *prep); If the first operation is present, then it is called before key creation (in the add/update case) or before the key semaphore is taken (in the update and instantiate cases). The second operation is called to clean up if the first was called. preparse() is given the opportunity to fill in the following structure: struct key_preparsed_payload { char *description; void *type_data[2]; void *payload; const void *data; size_t datalen; size_t quotalen; }; Before the preparser is called, the first three fields will have been cleared, the payload pointer and size will be stored in data and datalen and the default quota size from the key_type struct will be stored into quotalen. The preparser may parse the payload in any way it likes and may store data in the type_data[] and payload fields for use by the instantiate() and update() ops. The preparser may also propose a description for the key by attaching it as a string to the description field. This can be used by passing a NULL or "" description to the add_key() system call or the key_create_or_update() function. This cannot work with request_key() as that required the description to tell the upcall about the key to be created. This, for example permits keys that store PGP public keys to generate their own name from the user ID and public key fingerprint in the key. The instantiate() and update() operations are then modified to look like this: int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); int (*update)(struct key *key, struct key_preparsed_payload *prep); and the new payload data is passed in *prep, whether or not it was preparsed. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'security')
-rw-r--r--security/keys/encrypted-keys/encrypted.c16
-rw-r--r--security/keys/key.c114
-rw-r--r--security/keys/keyctl.c18
-rw-r--r--security/keys/keyring.c6
-rw-r--r--security/keys/request_key_auth.c8
-rw-r--r--security/keys/trusted.c16
-rw-r--r--security/keys/user_defined.c14
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 */
776static int encrypted_instantiate(struct key *key, const void *data, 776static 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 */
837static int encrypted_update(struct key *key, const void *data, size_t datalen) 838static 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 */
414static int __key_instantiate_and_link(struct key *key, 414static 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
511error_free_preparse:
512 if (key->type->preparse)
513 key->type->free_preparse(&prep);
514error:
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 */
708static inline key_ref_t __key_update(key_ref_t key_ref, 722static 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: 891error_link_end:
858 __key_link_end(keyring, ktype, prealloc); 892 __key_link_end(keyring, ktype, prealloc);
859 error_2: 893error_free_prep:
894 if (ktype->preparse)
895 ktype->free_preparse(&prep);
896error_put_type:
860 key_type_put(ktype); 897 key_type_put(ktype);
861 error: 898error:
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}
874EXPORT_SYMBOL(key_create_or_update); 910EXPORT_SYMBOL(key_create_or_update);
875 911
@@ -888,6 +924,7 @@ EXPORT_SYMBOL(key_create_or_update);
888 */ 924 */
889int key_update(key_ref_t key_ref, const void *payload, size_t plen) 925int 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);
964error:
915 return ret; 965 return ret;
916} 966}
917EXPORT_SYMBOL(key_update); 967EXPORT_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 */
68static int keyring_instantiate(struct key *keyring, 68static int keyring_instantiate(struct key *keyring,
69 const void *data, size_t datalen); 69 struct key_preparsed_payload *prep);
70static int keyring_match(const struct key *keyring, const void *criterion); 70static int keyring_match(const struct key *keyring, const void *criterion);
71static void keyring_revoke(struct key *keyring); 71static void keyring_revoke(struct key *keyring);
72static void keyring_destroy(struct key *keyring); 72static 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 */
123static int keyring_instantiate(struct key *keyring, 123static 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
22static int request_key_auth_instantiate(struct key *, const void *, size_t); 22static int request_key_auth_instantiate(struct key *,
23 struct key_preparsed_payload *);
23static void request_key_auth_describe(const struct key *, struct seq_file *); 24static void request_key_auth_describe(const struct key *, struct seq_file *);
24static void request_key_auth_revoke(struct key *); 25static void request_key_auth_revoke(struct key *);
25static void request_key_auth_destroy(struct key *); 26static 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 */
44static int request_key_auth_instantiate(struct key *key, 45static 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 */
930static int trusted_instantiate(struct key *key, const void *data, 930static 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 */
1014static int trusted_update(struct key *key, const void *data, size_t datalen) 1015static 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 */
61int user_instantiate(struct key *key, const void *data, size_t datalen) 61int 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 */
95int user_update(struct key *key, const void *data, size_t datalen) 96int 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;