aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/security/keys.txt50
-rw-r--r--fs/cifs/cifs_spnego.c6
-rw-r--r--fs/cifs/cifsacl.c8
-rw-r--r--include/keys/user-type.h6
-rw-r--r--include/linux/key-type.h35
-rw-r--r--net/ceph/crypto.c9
-rw-r--r--net/dns_resolver/dns_key.c6
-rw-r--r--net/rxrpc/ar-key.c40
-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
15 files changed, 250 insertions, 102 deletions
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index aa0dbd74b71b..7d9ca92022d8 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -412,6 +412,10 @@ The main syscalls are:
412 to the keyring. In this case, an error will be generated if the process 412 to the keyring. In this case, an error will be generated if the process
413 does not have permission to write to the keyring. 413 does not have permission to write to the keyring.
414 414
415 If the key type supports it, if the description is NULL or an empty
416 string, the key type will try and generate a description from the content
417 of the payload.
418
415 The payload is optional, and the pointer can be NULL if not required by 419 The payload is optional, and the pointer can be NULL if not required by
416 the type. The payload is plen in size, and plen can be zero for an empty 420 the type. The payload is plen in size, and plen can be zero for an empty
417 payload. 421 payload.
@@ -1114,12 +1118,53 @@ The structure has a number of fields, some of which are mandatory:
1114 it should return 0. 1118 it should return 0.
1115 1119
1116 1120
1117 (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); 1121 (*) int (*preparse)(struct key_preparsed_payload *prep);
1122
1123 This optional method permits the key type to attempt to parse payload
1124 before a key is created (add key) or the key semaphore is taken (update or
1125 instantiate key). The structure pointed to by prep looks like:
1126
1127 struct key_preparsed_payload {
1128 char *description;
1129 void *type_data[2];
1130 void *payload;
1131 const void *data;
1132 size_t datalen;
1133 size_t quotalen;
1134 };
1135
1136 Before calling the method, the caller will fill in data and datalen with
1137 the payload blob parameters; quotalen will be filled in with the default
1138 quota size from the key type and the rest will be cleared.
1139
1140 If a description can be proposed from the payload contents, that should be
1141 attached as a string to the description field. This will be used for the
1142 key description if the caller of add_key() passes NULL or "".
1143
1144 The method can attach anything it likes to type_data[] and payload. These
1145 are merely passed along to the instantiate() or update() operations.
1146
1147 The method should return 0 if success ful or a negative error code
1148 otherwise.
1149
1150
1151 (*) void (*free_preparse)(struct key_preparsed_payload *prep);
1152
1153 This method is only required if the preparse() method is provided,
1154 otherwise it is unused. It cleans up anything attached to the
1155 description, type_data and payload fields of the key_preparsed_payload
1156 struct as filled in by the preparse() method.
1157
1158
1159 (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
1118 1160
1119 This method is called to attach a payload to a key during construction. 1161 This method is called to attach a payload to a key during construction.
1120 The payload attached need not bear any relation to the data passed to this 1162 The payload attached need not bear any relation to the data passed to this
1121 function. 1163 function.
1122 1164
1165 The prep->data and prep->datalen fields will define the original payload
1166 blob. If preparse() was supplied then other fields may be filled in also.
1167
1123 If the amount of data attached to the key differs from the size in 1168 If the amount of data attached to the key differs from the size in
1124 keytype->def_datalen, then key_payload_reserve() should be called. 1169 keytype->def_datalen, then key_payload_reserve() should be called.
1125 1170
@@ -1135,6 +1180,9 @@ The structure has a number of fields, some of which are mandatory:
1135 If this type of key can be updated, then this method should be provided. 1180 If this type of key can be updated, then this method should be provided.
1136 It is called to update a key's payload from the blob of data provided. 1181 It is called to update a key's payload from the blob of data provided.
1137 1182
1183 The prep->data and prep->datalen fields will define the original payload
1184 blob. If preparse() was supplied then other fields may be filled in also.
1185
1138 key_payload_reserve() should be called if the data length might change 1186 key_payload_reserve() should be called if the data length might change
1139 before any changes are actually made. Note that if this succeeds, the type 1187 before any changes are actually made. Note that if this succeeds, the type
1140 is committed to changing the key because it's already been altered, so all 1188 is committed to changing the key because it's already been altered, so all
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index e622863b292f..086f381d6489 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -31,18 +31,18 @@
31 31
32/* create a new cifs key */ 32/* create a new cifs key */
33static int 33static int
34cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) 34cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
35{ 35{
36 char *payload; 36 char *payload;
37 int ret; 37 int ret;
38 38
39 ret = -ENOMEM; 39 ret = -ENOMEM;
40 payload = kmalloc(datalen, GFP_KERNEL); 40 payload = kmalloc(prep->datalen, GFP_KERNEL);
41 if (!payload) 41 if (!payload)
42 goto error; 42 goto error;
43 43
44 /* attach the data */ 44 /* attach the data */
45 memcpy(payload, data, datalen); 45 memcpy(payload, prep->data, prep->datalen);
46 key->payload.data = payload; 46 key->payload.data = payload;
47 ret = 0; 47 ret = 0;
48 48
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 05f4dc263a23..f3c60e264ca8 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = {
167}; 167};
168 168
169static int 169static int
170cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen) 170cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
171{ 171{
172 char *payload; 172 char *payload;
173 173
174 payload = kmalloc(datalen, GFP_KERNEL); 174 payload = kmalloc(prep->datalen, GFP_KERNEL);
175 if (!payload) 175 if (!payload)
176 return -ENOMEM; 176 return -ENOMEM;
177 177
178 memcpy(payload, data, datalen); 178 memcpy(payload, prep->data, prep->datalen);
179 key->payload.data = payload; 179 key->payload.data = payload;
180 key->datalen = datalen; 180 key->datalen = prep->datalen;
181 return 0; 181 return 0;
182} 182}
183 183
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index bc9ec1d7698c..5e452c84f1e6 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -35,8 +35,10 @@ struct user_key_payload {
35extern struct key_type key_type_user; 35extern struct key_type key_type_user;
36extern struct key_type key_type_logon; 36extern struct key_type key_type_logon;
37 37
38extern int user_instantiate(struct key *key, const void *data, size_t datalen); 38struct key_preparsed_payload;
39extern int user_update(struct key *key, const void *data, size_t datalen); 39
40extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep);
41extern int user_update(struct key *key, struct key_preparsed_payload *prep);
40extern int user_match(const struct key *key, const void *criterion); 42extern int user_match(const struct key *key, const void *criterion);
41extern void user_revoke(struct key *key); 43extern void user_revoke(struct key *key);
42extern void user_destroy(struct key *key); 44extern void user_destroy(struct key *key);
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index f0c651cda7b0..518a53afb9ea 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -26,6 +26,27 @@ struct key_construction {
26 struct key *authkey;/* authorisation for key being constructed */ 26 struct key *authkey;/* authorisation for key being constructed */
27}; 27};
28 28
29/*
30 * Pre-parsed payload, used by key add, update and instantiate.
31 *
32 * This struct will be cleared and data and datalen will be set with the data
33 * and length parameters from the caller and quotalen will be set from
34 * def_datalen from the key type. Then if the preparse() op is provided by the
35 * key type, that will be called. Then the struct will be passed to the
36 * instantiate() or the update() op.
37 *
38 * If the preparse() op is given, the free_preparse() op will be called to
39 * clear the contents.
40 */
41struct key_preparsed_payload {
42 char *description; /* Proposed key description (or NULL) */
43 void *type_data[2]; /* Private key-type data */
44 void *payload; /* Proposed payload */
45 const void *data; /* Raw data */
46 size_t datalen; /* Raw datalen */
47 size_t quotalen; /* Quota length for proposed payload */
48};
49
29typedef int (*request_key_actor_t)(struct key_construction *key, 50typedef int (*request_key_actor_t)(struct key_construction *key,
30 const char *op, void *aux); 51 const char *op, void *aux);
31 52
@@ -45,18 +66,28 @@ struct key_type {
45 /* vet a description */ 66 /* vet a description */
46 int (*vet_description)(const char *description); 67 int (*vet_description)(const char *description);
47 68
69 /* Preparse the data blob from userspace that is to be the payload,
70 * generating a proposed description and payload that will be handed to
71 * the instantiate() and update() ops.
72 */
73 int (*preparse)(struct key_preparsed_payload *prep);
74
75 /* Free a preparse data structure.
76 */
77 void (*free_preparse)(struct key_preparsed_payload *prep);
78
48 /* instantiate a key of this type 79 /* instantiate a key of this type
49 * - this method should call key_payload_reserve() to determine if the 80 * - this method should call key_payload_reserve() to determine if the
50 * user's quota will hold the payload 81 * user's quota will hold the payload
51 */ 82 */
52 int (*instantiate)(struct key *key, const void *data, size_t datalen); 83 int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
53 84
54 /* update a key of this type (optional) 85 /* update a key of this type (optional)
55 * - this method should call key_payload_reserve() to recalculate the 86 * - this method should call key_payload_reserve() to recalculate the
56 * quota consumption 87 * quota consumption
57 * - the key must be locked against read when modifying 88 * - the key must be locked against read when modifying
58 */ 89 */
59 int (*update)(struct key *key, const void *data, size_t datalen); 90 int (*update)(struct key *key, struct key_preparsed_payload *prep);
60 91
61 /* match a key against a description */ 92 /* match a key against a description */
62 int (*match)(const struct key *key, const void *desc); 93 int (*match)(const struct key *key, const void *desc);
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 9da7fdd3cd8a..af14cb425164 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -423,14 +423,15 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
423 } 423 }
424} 424}
425 425
426int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) 426int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
427{ 427{
428 struct ceph_crypto_key *ckey; 428 struct ceph_crypto_key *ckey;
429 size_t datalen = prep->datalen;
429 int ret; 430 int ret;
430 void *p; 431 void *p;
431 432
432 ret = -EINVAL; 433 ret = -EINVAL;
433 if (datalen <= 0 || datalen > 32767 || !data) 434 if (datalen <= 0 || datalen > 32767 || !prep->data)
434 goto err; 435 goto err;
435 436
436 ret = key_payload_reserve(key, datalen); 437 ret = key_payload_reserve(key, datalen);
@@ -443,8 +444,8 @@ int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
443 goto err; 444 goto err;
444 445
445 /* TODO ceph_crypto_key_decode should really take const input */ 446 /* TODO ceph_crypto_key_decode should really take const input */
446 p = (void *)data; 447 p = (void *)prep->data;
447 ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); 448 ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen);
448 if (ret < 0) 449 if (ret < 0)
449 goto err_ckey; 450 goto err_ckey;
450 451
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index d9507dd05818..859ab8b6ec34 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -59,13 +59,13 @@ const struct cred *dns_resolver_cache;
59 * "ip1,ip2,...#foo=bar" 59 * "ip1,ip2,...#foo=bar"
60 */ 60 */
61static int 61static int
62dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen) 62dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
63{ 63{
64 struct user_key_payload *upayload; 64 struct user_key_payload *upayload;
65 unsigned long derrno; 65 unsigned long derrno;
66 int ret; 66 int ret;
67 size_t result_len = 0; 67 size_t datalen = prep->datalen, result_len = 0;
68 const char *data = _data, *end, *opt; 68 const char *data = prep->data, *end, *opt;
69 69
70 kenter("%%%d,%s,'%*.*s',%zu", 70 kenter("%%%d,%s,'%*.*s',%zu",
71 key->serial, key->description, 71 key->serial, key->description,
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 8b1f9f49960f..106c5a6b1ab2 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -26,8 +26,8 @@
26#include "ar-internal.h" 26#include "ar-internal.h"
27 27
28static int rxrpc_vet_description_s(const char *); 28static int rxrpc_vet_description_s(const char *);
29static int rxrpc_instantiate(struct key *, const void *, size_t); 29static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *);
30static int rxrpc_instantiate_s(struct key *, const void *, size_t); 30static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *);
31static void rxrpc_destroy(struct key *); 31static void rxrpc_destroy(struct key *);
32static void rxrpc_destroy_s(struct key *); 32static void rxrpc_destroy_s(struct key *);
33static void rxrpc_describe(const struct key *, struct seq_file *); 33static void rxrpc_describe(const struct key *, struct seq_file *);
@@ -678,7 +678,7 @@ error:
678 * 678 *
679 * if no data is provided, then a no-security key is made 679 * if no data is provided, then a no-security key is made
680 */ 680 */
681static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) 681static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep)
682{ 682{
683 const struct rxrpc_key_data_v1 *v1; 683 const struct rxrpc_key_data_v1 *v1;
684 struct rxrpc_key_token *token, **pp; 684 struct rxrpc_key_token *token, **pp;
@@ -686,26 +686,26 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
686 u32 kver; 686 u32 kver;
687 int ret; 687 int ret;
688 688
689 _enter("{%x},,%zu", key_serial(key), datalen); 689 _enter("{%x},,%zu", key_serial(key), prep->datalen);
690 690
691 /* handle a no-security key */ 691 /* handle a no-security key */
692 if (!data && datalen == 0) 692 if (!prep->data && prep->datalen == 0)
693 return 0; 693 return 0;
694 694
695 /* determine if the XDR payload format is being used */ 695 /* determine if the XDR payload format is being used */
696 if (datalen > 7 * 4) { 696 if (prep->datalen > 7 * 4) {
697 ret = rxrpc_instantiate_xdr(key, data, datalen); 697 ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen);
698 if (ret != -EPROTO) 698 if (ret != -EPROTO)
699 return ret; 699 return ret;
700 } 700 }
701 701
702 /* get the key interface version number */ 702 /* get the key interface version number */
703 ret = -EINVAL; 703 ret = -EINVAL;
704 if (datalen <= 4 || !data) 704 if (prep->datalen <= 4 || !prep->data)
705 goto error; 705 goto error;
706 memcpy(&kver, data, sizeof(kver)); 706 memcpy(&kver, prep->data, sizeof(kver));
707 data += sizeof(kver); 707 prep->data += sizeof(kver);
708 datalen -= sizeof(kver); 708 prep->datalen -= sizeof(kver);
709 709
710 _debug("KEY I/F VERSION: %u", kver); 710 _debug("KEY I/F VERSION: %u", kver);
711 711
@@ -715,11 +715,11 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
715 715
716 /* deal with a version 1 key */ 716 /* deal with a version 1 key */
717 ret = -EINVAL; 717 ret = -EINVAL;
718 if (datalen < sizeof(*v1)) 718 if (prep->datalen < sizeof(*v1))
719 goto error; 719 goto error;
720 720
721 v1 = data; 721 v1 = prep->data;
722 if (datalen != sizeof(*v1) + v1->ticket_length) 722 if (prep->datalen != sizeof(*v1) + v1->ticket_length)
723 goto error; 723 goto error;
724 724
725 _debug("SCIX: %u", v1->security_index); 725 _debug("SCIX: %u", v1->security_index);
@@ -784,17 +784,17 @@ error:
784 * instantiate a server secret key 784 * instantiate a server secret key
785 * data should be a pointer to the 8-byte secret key 785 * data should be a pointer to the 8-byte secret key
786 */ 786 */
787static int rxrpc_instantiate_s(struct key *key, const void *data, 787static int rxrpc_instantiate_s(struct key *key,
788 size_t datalen) 788 struct key_preparsed_payload *prep)
789{ 789{
790 struct crypto_blkcipher *ci; 790 struct crypto_blkcipher *ci;
791 791
792 _enter("{%x},,%zu", key_serial(key), datalen); 792 _enter("{%x},,%zu", key_serial(key), prep->datalen);
793 793
794 if (datalen != 8) 794 if (prep->datalen != 8)
795 return -EINVAL; 795 return -EINVAL;
796 796
797 memcpy(&key->type_data, data, 8); 797 memcpy(&key->type_data, prep->data, 8);
798 798
799 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 799 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
800 if (IS_ERR(ci)) { 800 if (IS_ERR(ci)) {
@@ -802,7 +802,7 @@ static int rxrpc_instantiate_s(struct key *key, const void *data,
802 return PTR_ERR(ci); 802 return PTR_ERR(ci);
803 } 803 }
804 804
805 if (crypto_blkcipher_setkey(ci, data, 8) < 0) 805 if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
806 BUG(); 806 BUG();
807 807
808 key->payload.data = ci; 808 key->payload.data = ci;
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;