aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-07-22 16:51:20 -0400
committerDavid Howells <dhowells@redhat.com>2014-07-22 16:51:20 -0400
commita19e3c22b34ae599eafd9fd05c887fc8e7ec2e3a (patch)
tree44a93a6da7868c58606f39421870b32a920b3e77
parent32c2e6752ff0f48fe03b9e1c7c64bde580a840d2 (diff)
parentf1dcde91a3503f68ef209667a8798ead2b50b02a (diff)
Merge tag 'keys-preparse-1-20140722' into keys-next
Here are a set of changes that make all but encrypted and trusted keys use preparsing. Unfortunately, encrypted and trusted keys incorrectly use the update op to alter a key, so other changes will need to be made for them. These changes permit payload parsing when instantiating or updating a key to be done before locks are taken and to determine the amount of quota that will be required in advance. The latter will make it possible to do LRU discard before any locks are taken. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--Documentation/security/keys.txt14
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c27
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c2
-rw-r--r--fs/nfs/idmap.c8
-rw-r--r--include/keys/big_key-type.h3
-rw-r--r--include/keys/user-type.h3
-rw-r--r--include/linux/key-type.h5
-rw-r--r--net/ceph/crypto.c26
-rw-r--r--net/dns_resolver/dns_key.c43
-rw-r--r--net/rxrpc/ar-key.c165
-rw-r--r--security/keys/big_key.c41
-rw-r--r--security/keys/encrypted-keys/encrypted.c2
-rw-r--r--security/keys/key.c49
-rw-r--r--security/keys/keyring.c34
-rw-r--r--security/keys/request_key_auth.c13
-rw-r--r--security/keys/user_defined.c41
16 files changed, 291 insertions, 185 deletions
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index a4c33f1a7c6d..8727c194ca16 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -1150,20 +1150,24 @@ The structure has a number of fields, some of which are mandatory:
1150 const void *data; 1150 const void *data;
1151 size_t datalen; 1151 size_t datalen;
1152 size_t quotalen; 1152 size_t quotalen;
1153 time_t expiry;
1153 }; 1154 };
1154 1155
1155 Before calling the method, the caller will fill in data and datalen with 1156 Before calling the method, the caller will fill in data and datalen with
1156 the payload blob parameters; quotalen will be filled in with the default 1157 the payload blob parameters; quotalen will be filled in with the default
1157 quota size from the key type and the rest will be cleared. 1158 quota size from the key type; expiry will be set to TIME_T_MAX and the
1159 rest will be cleared.
1158 1160
1159 If a description can be proposed from the payload contents, that should be 1161 If a description can be proposed from the payload contents, that should be
1160 attached as a string to the description field. This will be used for the 1162 attached as a string to the description field. This will be used for the
1161 key description if the caller of add_key() passes NULL or "". 1163 key description if the caller of add_key() passes NULL or "".
1162 1164
1163 The method can attach anything it likes to type_data[] and payload. These 1165 The method can attach anything it likes to type_data[] and payload. These
1164 are merely passed along to the instantiate() or update() operations. 1166 are merely passed along to the instantiate() or update() operations. If
1167 set, the expiry time will be applied to the key if it is instantiated from
1168 this data.
1165 1169
1166 The method should return 0 if success ful or a negative error code 1170 The method should return 0 if successful or a negative error code
1167 otherwise. 1171 otherwise.
1168 1172
1169 1173
@@ -1172,7 +1176,9 @@ The structure has a number of fields, some of which are mandatory:
1172 This method is only required if the preparse() method is provided, 1176 This method is only required if the preparse() method is provided,
1173 otherwise it is unused. It cleans up anything attached to the 1177 otherwise it is unused. It cleans up anything attached to the
1174 description, type_data and payload fields of the key_preparsed_payload 1178 description, type_data and payload fields of the key_preparsed_payload
1175 struct as filled in by the preparse() method. 1179 struct as filled in by the preparse() method. It will always be called
1180 after preparse() returns successfully, even if instantiate() or update()
1181 succeed.
1176 1182
1177 1183
1178 (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); 1184 (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index b77eb5304788..21960a4e74e8 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -156,7 +156,7 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
156 pr_devel("==>%s()\n", __func__); 156 pr_devel("==>%s()\n", __func__);
157 157
158 if (subtype) { 158 if (subtype) {
159 subtype->destroy(prep->payload); 159 subtype->destroy(prep->payload[0]);
160 module_put(subtype->owner); 160 module_put(subtype->owner);
161 } 161 }
162 kfree(prep->type_data[1]); 162 kfree(prep->type_data[1]);
@@ -164,29 +164,6 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
164} 164}
165 165
166/* 166/*
167 * Instantiate a asymmetric_key defined key. The key was preparsed, so we just
168 * have to transfer the data here.
169 */
170static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
171{
172 int ret;
173
174 pr_devel("==>%s()\n", __func__);
175
176 ret = key_payload_reserve(key, prep->quotalen);
177 if (ret == 0) {
178 key->type_data.p[0] = prep->type_data[0];
179 key->type_data.p[1] = prep->type_data[1];
180 key->payload.data = prep->payload;
181 prep->type_data[0] = NULL;
182 prep->type_data[1] = NULL;
183 prep->payload = NULL;
184 }
185 pr_devel("<==%s() = %d\n", __func__, ret);
186 return ret;
187}
188
189/*
190 * dispose of the data dangling from the corpse of a asymmetric key 167 * dispose of the data dangling from the corpse of a asymmetric key
191 */ 168 */
192static void asymmetric_key_destroy(struct key *key) 169static void asymmetric_key_destroy(struct key *key)
@@ -205,7 +182,7 @@ struct key_type key_type_asymmetric = {
205 .name = "asymmetric", 182 .name = "asymmetric",
206 .preparse = asymmetric_key_preparse, 183 .preparse = asymmetric_key_preparse,
207 .free_preparse = asymmetric_key_free_preparse, 184 .free_preparse = asymmetric_key_free_preparse,
208 .instantiate = asymmetric_key_instantiate, 185 .instantiate = generic_key_instantiate,
209 .match = asymmetric_key_match, 186 .match = asymmetric_key_match,
210 .destroy = asymmetric_key_destroy, 187 .destroy = asymmetric_key_destroy,
211 .describe = asymmetric_key_describe, 188 .describe = asymmetric_key_describe,
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 382ef0d2ff2e..3fc8a0634ed7 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -177,7 +177,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
177 __module_get(public_key_subtype.owner); 177 __module_get(public_key_subtype.owner);
178 prep->type_data[0] = &public_key_subtype; 178 prep->type_data[0] = &public_key_subtype;
179 prep->type_data[1] = cert->fingerprint; 179 prep->type_data[1] = cert->fingerprint;
180 prep->payload = cert->pub; 180 prep->payload[0] = cert->pub;
181 prep->description = desc; 181 prep->description = desc;
182 prep->quotalen = 100; 182 prep->quotalen = 100;
183 183
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 567983d2c0eb..59b217a3266d 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -174,7 +174,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)
174 174
175static struct key_type key_type_id_resolver = { 175static struct key_type key_type_id_resolver = {
176 .name = "id_resolver", 176 .name = "id_resolver",
177 .instantiate = user_instantiate, 177 .preparse = user_preparse,
178 .free_preparse = user_free_preparse,
179 .instantiate = generic_key_instantiate,
178 .match = user_match, 180 .match = user_match,
179 .revoke = user_revoke, 181 .revoke = user_revoke,
180 .destroy = user_destroy, 182 .destroy = user_destroy,
@@ -394,7 +396,9 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {
394 396
395static struct key_type key_type_id_resolver_legacy = { 397static struct key_type key_type_id_resolver_legacy = {
396 .name = "id_legacy", 398 .name = "id_legacy",
397 .instantiate = user_instantiate, 399 .preparse = user_preparse,
400 .free_preparse = user_free_preparse,
401 .instantiate = generic_key_instantiate,
398 .match = user_match, 402 .match = user_match,
399 .revoke = user_revoke, 403 .revoke = user_revoke,
400 .destroy = user_destroy, 404 .destroy = user_destroy,
diff --git a/include/keys/big_key-type.h b/include/keys/big_key-type.h
index d69bc8af3292..e0970a578188 100644
--- a/include/keys/big_key-type.h
+++ b/include/keys/big_key-type.h
@@ -16,7 +16,8 @@
16 16
17extern struct key_type key_type_big_key; 17extern struct key_type key_type_big_key;
18 18
19extern int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep); 19extern int big_key_preparse(struct key_preparsed_payload *prep);
20extern void big_key_free_preparse(struct key_preparsed_payload *prep);
20extern void big_key_revoke(struct key *key); 21extern void big_key_revoke(struct key *key);
21extern void big_key_destroy(struct key *key); 22extern void big_key_destroy(struct key *key);
22extern void big_key_describe(const struct key *big_key, struct seq_file *m); 23extern void big_key_describe(const struct key *big_key, struct seq_file *m);
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index 5e452c84f1e6..3ab1873a4bfa 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -37,7 +37,8 @@ extern struct key_type key_type_logon;
37 37
38struct key_preparsed_payload; 38struct key_preparsed_payload;
39 39
40extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); 40extern int user_preparse(struct key_preparsed_payload *prep);
41extern void user_free_preparse(struct key_preparsed_payload *prep);
41extern int user_update(struct key *key, struct key_preparsed_payload *prep); 42extern int user_update(struct key *key, struct key_preparsed_payload *prep);
42extern int user_match(const struct key *key, const void *criterion); 43extern int user_match(const struct key *key, const void *criterion);
43extern void user_revoke(struct key *key); 44extern void user_revoke(struct key *key);
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index a74c3a84dfdd..44792ee649de 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -41,10 +41,11 @@ struct key_construction {
41struct key_preparsed_payload { 41struct key_preparsed_payload {
42 char *description; /* Proposed key description (or NULL) */ 42 char *description; /* Proposed key description (or NULL) */
43 void *type_data[2]; /* Private key-type data */ 43 void *type_data[2]; /* Private key-type data */
44 void *payload; /* Proposed payload */ 44 void *payload[2]; /* Proposed payload */
45 const void *data; /* Raw data */ 45 const void *data; /* Raw data */
46 size_t datalen; /* Raw datalen */ 46 size_t datalen; /* Raw datalen */
47 size_t quotalen; /* Quota length for proposed payload */ 47 size_t quotalen; /* Quota length for proposed payload */
48 time_t expiry; /* Expiry time of key */
48 bool trusted; /* True if key is trusted */ 49 bool trusted; /* True if key is trusted */
49}; 50};
50 51
@@ -159,5 +160,7 @@ static inline int key_negate_and_link(struct key *key,
159 return key_reject_and_link(key, timeout, ENOKEY, keyring, instkey); 160 return key_reject_and_link(key, timeout, ENOKEY, keyring, instkey);
160} 161}
161 162
163extern int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep);
164
162#endif /* CONFIG_KEYS */ 165#endif /* CONFIG_KEYS */
163#endif /* _LINUX_KEY_TYPE_H */ 166#endif /* _LINUX_KEY_TYPE_H */
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 6e7a236525b6..ffeba8f9dda9 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -8,6 +8,7 @@
8#include <linux/key-type.h> 8#include <linux/key-type.h>
9 9
10#include <keys/ceph-type.h> 10#include <keys/ceph-type.h>
11#include <keys/user-type.h>
11#include <linux/ceph/decode.h> 12#include <linux/ceph/decode.h>
12#include "crypto.h" 13#include "crypto.h"
13 14
@@ -423,8 +424,7 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
423 } 424 }
424} 425}
425 426
426static int ceph_key_instantiate(struct key *key, 427static int ceph_key_preparse(struct key_preparsed_payload *prep)
427 struct key_preparsed_payload *prep)
428{ 428{
429 struct ceph_crypto_key *ckey; 429 struct ceph_crypto_key *ckey;
430 size_t datalen = prep->datalen; 430 size_t datalen = prep->datalen;
@@ -435,10 +435,6 @@ static int ceph_key_instantiate(struct key *key,
435 if (datalen <= 0 || datalen > 32767 || !prep->data) 435 if (datalen <= 0 || datalen > 32767 || !prep->data)
436 goto err; 436 goto err;
437 437
438 ret = key_payload_reserve(key, datalen);
439 if (ret < 0)
440 goto err;
441
442 ret = -ENOMEM; 438 ret = -ENOMEM;
443 ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); 439 ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
444 if (!ckey) 440 if (!ckey)
@@ -450,7 +446,8 @@ static int ceph_key_instantiate(struct key *key,
450 if (ret < 0) 446 if (ret < 0)
451 goto err_ckey; 447 goto err_ckey;
452 448
453 key->payload.data = ckey; 449 prep->payload[0] = ckey;
450 prep->quotalen = datalen;
454 return 0; 451 return 0;
455 452
456err_ckey: 453err_ckey:
@@ -459,12 +456,15 @@ err:
459 return ret; 456 return ret;
460} 457}
461 458
462static int ceph_key_match(const struct key *key, const void *description) 459static void ceph_key_free_preparse(struct key_preparsed_payload *prep)
463{ 460{
464 return strcmp(key->description, description) == 0; 461 struct ceph_crypto_key *ckey = prep->payload[0];
462 ceph_crypto_key_destroy(ckey);
463 kfree(ckey);
465} 464}
466 465
467static void ceph_key_destroy(struct key *key) { 466static void ceph_key_destroy(struct key *key)
467{
468 struct ceph_crypto_key *ckey = key->payload.data; 468 struct ceph_crypto_key *ckey = key->payload.data;
469 469
470 ceph_crypto_key_destroy(ckey); 470 ceph_crypto_key_destroy(ckey);
@@ -473,8 +473,10 @@ static void ceph_key_destroy(struct key *key) {
473 473
474struct key_type key_type_ceph = { 474struct key_type key_type_ceph = {
475 .name = "ceph", 475 .name = "ceph",
476 .instantiate = ceph_key_instantiate, 476 .preparse = ceph_key_preparse,
477 .match = ceph_key_match, 477 .free_preparse = ceph_key_free_preparse,
478 .instantiate = generic_key_instantiate,
479 .match = user_match,
478 .destroy = ceph_key_destroy, 480 .destroy = ceph_key_destroy,
479}; 481};
480 482
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index bf8584339048..f380b2c58178 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -46,7 +46,7 @@ const struct cred *dns_resolver_cache;
46#define DNS_ERRORNO_OPTION "dnserror" 46#define DNS_ERRORNO_OPTION "dnserror"
47 47
48/* 48/*
49 * Instantiate a user defined key for dns_resolver. 49 * Preparse instantiation data for a dns_resolver key.
50 * 50 *
51 * The data must be a NUL-terminated string, with the NUL char accounted in 51 * The data must be a NUL-terminated string, with the NUL char accounted in
52 * datalen. 52 * datalen.
@@ -58,17 +58,15 @@ const struct cred *dns_resolver_cache;
58 * "ip1,ip2,...#foo=bar" 58 * "ip1,ip2,...#foo=bar"
59 */ 59 */
60static int 60static int
61dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) 61dns_resolver_preparse(struct key_preparsed_payload *prep)
62{ 62{
63 struct user_key_payload *upayload; 63 struct user_key_payload *upayload;
64 unsigned long derrno; 64 unsigned long derrno;
65 int ret; 65 int ret;
66 size_t datalen = prep->datalen, result_len = 0; 66 int datalen = prep->datalen, result_len = 0;
67 const char *data = prep->data, *end, *opt; 67 const char *data = prep->data, *end, *opt;
68 68
69 kenter("%%%d,%s,'%*.*s',%zu", 69 kenter("'%*.*s',%u", datalen, datalen, data, datalen);
70 key->serial, key->description,
71 (int)datalen, (int)datalen, data, datalen);
72 70
73 if (datalen <= 1 || !data || data[datalen - 1] != '\0') 71 if (datalen <= 1 || !data || data[datalen - 1] != '\0')
74 return -EINVAL; 72 return -EINVAL;
@@ -95,8 +93,7 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
95 opt_len = next_opt - opt; 93 opt_len = next_opt - opt;
96 if (!opt_len) { 94 if (!opt_len) {
97 printk(KERN_WARNING 95 printk(KERN_WARNING
98 "Empty option to dns_resolver key %d\n", 96 "Empty option to dns_resolver key\n");
99 key->serial);
100 return -EINVAL; 97 return -EINVAL;
101 } 98 }
102 99
@@ -125,30 +122,28 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
125 goto bad_option_value; 122 goto bad_option_value;
126 123
127 kdebug("dns error no. = %lu", derrno); 124 kdebug("dns error no. = %lu", derrno);
128 key->type_data.x[0] = -derrno; 125 prep->type_data[0] = ERR_PTR(-derrno);
129 continue; 126 continue;
130 } 127 }
131 128
132 bad_option_value: 129 bad_option_value:
133 printk(KERN_WARNING 130 printk(KERN_WARNING
134 "Option '%*.*s' to dns_resolver key %d:" 131 "Option '%*.*s' to dns_resolver key:"
135 " bad/missing value\n", 132 " bad/missing value\n",
136 opt_nlen, opt_nlen, opt, key->serial); 133 opt_nlen, opt_nlen, opt);
137 return -EINVAL; 134 return -EINVAL;
138 } while (opt = next_opt + 1, opt < end); 135 } while (opt = next_opt + 1, opt < end);
139 } 136 }
140 137
141 /* don't cache the result if we're caching an error saying there's no 138 /* don't cache the result if we're caching an error saying there's no
142 * result */ 139 * result */
143 if (key->type_data.x[0]) { 140 if (prep->type_data[0]) {
144 kleave(" = 0 [h_error %ld]", key->type_data.x[0]); 141 kleave(" = 0 [h_error %ld]", PTR_ERR(prep->type_data[0]));
145 return 0; 142 return 0;
146 } 143 }
147 144
148 kdebug("store result"); 145 kdebug("store result");
149 ret = key_payload_reserve(key, result_len); 146 prep->quotalen = result_len;
150 if (ret < 0)
151 return -EINVAL;
152 147
153 upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL); 148 upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL);
154 if (!upayload) { 149 if (!upayload) {
@@ -159,13 +154,23 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
159 upayload->datalen = result_len; 154 upayload->datalen = result_len;
160 memcpy(upayload->data, data, result_len); 155 memcpy(upayload->data, data, result_len);
161 upayload->data[result_len] = '\0'; 156 upayload->data[result_len] = '\0';
162 rcu_assign_pointer(key->payload.data, upayload);
163 157
158 prep->payload[0] = upayload;
164 kleave(" = 0"); 159 kleave(" = 0");
165 return 0; 160 return 0;
166} 161}
167 162
168/* 163/*
164 * Clean up the preparse data
165 */
166static void dns_resolver_free_preparse(struct key_preparsed_payload *prep)
167{
168 pr_devel("==>%s()\n", __func__);
169
170 kfree(prep->payload[0]);
171}
172
173/*
169 * The description is of the form "[<type>:]<domain_name>" 174 * The description is of the form "[<type>:]<domain_name>"
170 * 175 *
171 * The domain name may be a simple name or an absolute domain name (which 176 * The domain name may be a simple name or an absolute domain name (which
@@ -234,7 +239,9 @@ static long dns_resolver_read(const struct key *key,
234 239
235struct key_type key_type_dns_resolver = { 240struct key_type key_type_dns_resolver = {
236 .name = "dns_resolver", 241 .name = "dns_resolver",
237 .instantiate = dns_resolver_instantiate, 242 .preparse = dns_resolver_preparse,
243 .free_preparse = dns_resolver_free_preparse,
244 .instantiate = generic_key_instantiate,
238 .match = dns_resolver_match, 245 .match = dns_resolver_match,
239 .revoke = user_revoke, 246 .revoke = user_revoke,
240 .destroy = user_destroy, 247 .destroy = user_destroy,
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 0ad080790a32..3907add75932 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -26,8 +26,10 @@
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 *, struct key_preparsed_payload *); 29static int rxrpc_preparse(struct key_preparsed_payload *);
30static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); 30static int rxrpc_preparse_s(struct key_preparsed_payload *);
31static void rxrpc_free_preparse(struct key_preparsed_payload *);
32static void rxrpc_free_preparse_s(struct key_preparsed_payload *);
31static void rxrpc_destroy(struct key *); 33static void rxrpc_destroy(struct key *);
32static void rxrpc_destroy_s(struct key *); 34static void rxrpc_destroy_s(struct key *);
33static void rxrpc_describe(const struct key *, struct seq_file *); 35static void rxrpc_describe(const struct key *, struct seq_file *);
@@ -39,7 +41,9 @@ static long rxrpc_read(const struct key *, char __user *, size_t);
39 */ 41 */
40struct key_type key_type_rxrpc = { 42struct key_type key_type_rxrpc = {
41 .name = "rxrpc", 43 .name = "rxrpc",
42 .instantiate = rxrpc_instantiate, 44 .preparse = rxrpc_preparse,
45 .free_preparse = rxrpc_free_preparse,
46 .instantiate = generic_key_instantiate,
43 .match = user_match, 47 .match = user_match,
44 .destroy = rxrpc_destroy, 48 .destroy = rxrpc_destroy,
45 .describe = rxrpc_describe, 49 .describe = rxrpc_describe,
@@ -54,7 +58,9 @@ EXPORT_SYMBOL(key_type_rxrpc);
54struct key_type key_type_rxrpc_s = { 58struct key_type key_type_rxrpc_s = {
55 .name = "rxrpc_s", 59 .name = "rxrpc_s",
56 .vet_description = rxrpc_vet_description_s, 60 .vet_description = rxrpc_vet_description_s,
57 .instantiate = rxrpc_instantiate_s, 61 .preparse = rxrpc_preparse_s,
62 .free_preparse = rxrpc_free_preparse_s,
63 .instantiate = generic_key_instantiate,
58 .match = user_match, 64 .match = user_match,
59 .destroy = rxrpc_destroy_s, 65 .destroy = rxrpc_destroy_s,
60 .describe = rxrpc_describe, 66 .describe = rxrpc_describe,
@@ -81,13 +87,13 @@ static int rxrpc_vet_description_s(const char *desc)
81 * parse an RxKAD type XDR format token 87 * parse an RxKAD type XDR format token
82 * - the caller guarantees we have at least 4 words 88 * - the caller guarantees we have at least 4 words
83 */ 89 */
84static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, 90static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
85 unsigned int toklen) 91 size_t datalen,
92 const __be32 *xdr, unsigned int toklen)
86{ 93{
87 struct rxrpc_key_token *token, **pptoken; 94 struct rxrpc_key_token *token, **pptoken;
88 size_t plen; 95 size_t plen;
89 u32 tktlen; 96 u32 tktlen;
90 int ret;
91 97
92 _enter(",{%x,%x,%x,%x},%u", 98 _enter(",{%x,%x,%x,%x},%u",
93 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 99 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
@@ -103,9 +109,7 @@ static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
103 return -EKEYREJECTED; 109 return -EKEYREJECTED;
104 110
105 plen = sizeof(*token) + sizeof(*token->kad) + tktlen; 111 plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
106 ret = key_payload_reserve(key, key->datalen + plen); 112 prep->quotalen = datalen + plen;
107 if (ret < 0)
108 return ret;
109 113
110 plen -= sizeof(*token); 114 plen -= sizeof(*token);
111 token = kzalloc(sizeof(*token), GFP_KERNEL); 115 token = kzalloc(sizeof(*token), GFP_KERNEL);
@@ -146,16 +150,16 @@ static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
146 token->kad->ticket[6], token->kad->ticket[7]); 150 token->kad->ticket[6], token->kad->ticket[7]);
147 151
148 /* count the number of tokens attached */ 152 /* count the number of tokens attached */
149 key->type_data.x[0]++; 153 prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1);
150 154
151 /* attach the data */ 155 /* attach the data */
152 for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 156 for (pptoken = (struct rxrpc_key_token **)&prep->payload[0];
153 *pptoken; 157 *pptoken;
154 pptoken = &(*pptoken)->next) 158 pptoken = &(*pptoken)->next)
155 continue; 159 continue;
156 *pptoken = token; 160 *pptoken = token;
157 if (token->kad->expiry < key->expiry) 161 if (token->kad->expiry < prep->expiry)
158 key->expiry = token->kad->expiry; 162 prep->expiry = token->kad->expiry;
159 163
160 _leave(" = 0"); 164 _leave(" = 0");
161 return 0; 165 return 0;
@@ -418,8 +422,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
418 * parse an RxK5 type XDR format token 422 * parse an RxK5 type XDR format token
419 * - the caller guarantees we have at least 4 words 423 * - the caller guarantees we have at least 4 words
420 */ 424 */
421static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr, 425static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep,
422 unsigned int toklen) 426 size_t datalen,
427 const __be32 *xdr, unsigned int toklen)
423{ 428{
424 struct rxrpc_key_token *token, **pptoken; 429 struct rxrpc_key_token *token, **pptoken;
425 struct rxk5_key *rxk5; 430 struct rxk5_key *rxk5;
@@ -432,9 +437,7 @@ static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr,
432 437
433 /* reserve some payload space for this subkey - the length of the token 438 /* reserve some payload space for this subkey - the length of the token
434 * is a reasonable approximation */ 439 * is a reasonable approximation */
435 ret = key_payload_reserve(key, key->datalen + toklen); 440 prep->quotalen = datalen + toklen;
436 if (ret < 0)
437 return ret;
438 441
439 token = kzalloc(sizeof(*token), GFP_KERNEL); 442 token = kzalloc(sizeof(*token), GFP_KERNEL);
440 if (!token) 443 if (!token)
@@ -520,14 +523,14 @@ static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr,
520 if (toklen != 0) 523 if (toklen != 0)
521 goto inval; 524 goto inval;
522 525
523 /* attach the payload to the key */ 526 /* attach the payload */
524 for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 527 for (pptoken = (struct rxrpc_key_token **)&prep->payload[0];
525 *pptoken; 528 *pptoken;
526 pptoken = &(*pptoken)->next) 529 pptoken = &(*pptoken)->next)
527 continue; 530 continue;
528 *pptoken = token; 531 *pptoken = token;
529 if (token->kad->expiry < key->expiry) 532 if (token->kad->expiry < prep->expiry)
530 key->expiry = token->kad->expiry; 533 prep->expiry = token->kad->expiry;
531 534
532 _leave(" = 0"); 535 _leave(" = 0");
533 return 0; 536 return 0;
@@ -545,16 +548,17 @@ error:
545 * attempt to parse the data as the XDR format 548 * attempt to parse the data as the XDR format
546 * - the caller guarantees we have more than 7 words 549 * - the caller guarantees we have more than 7 words
547 */ 550 */
548static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) 551static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
549{ 552{
550 const __be32 *xdr = data, *token; 553 const __be32 *xdr = prep->data, *token;
551 const char *cp; 554 const char *cp;
552 unsigned int len, tmp, loop, ntoken, toklen, sec_ix; 555 unsigned int len, tmp, loop, ntoken, toklen, sec_ix;
556 size_t datalen = prep->datalen;
553 int ret; 557 int ret;
554 558
555 _enter(",{%x,%x,%x,%x},%zu", 559 _enter(",{%x,%x,%x,%x},%zu",
556 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 560 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
557 datalen); 561 prep->datalen);
558 562
559 if (datalen > AFSTOKEN_LENGTH_MAX) 563 if (datalen > AFSTOKEN_LENGTH_MAX)
560 goto not_xdr; 564 goto not_xdr;
@@ -635,13 +639,13 @@ static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datal
635 639
636 switch (sec_ix) { 640 switch (sec_ix) {
637 case RXRPC_SECURITY_RXKAD: 641 case RXRPC_SECURITY_RXKAD:
638 ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); 642 ret = rxrpc_preparse_xdr_rxkad(prep, datalen, xdr, toklen);
639 if (ret != 0) 643 if (ret != 0)
640 goto error; 644 goto error;
641 break; 645 break;
642 646
643 case RXRPC_SECURITY_RXK5: 647 case RXRPC_SECURITY_RXK5:
644 ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen); 648 ret = rxrpc_preparse_xdr_rxk5(prep, datalen, xdr, toklen);
645 if (ret != 0) 649 if (ret != 0)
646 goto error; 650 goto error;
647 break; 651 break;
@@ -665,8 +669,9 @@ error:
665} 669}
666 670
667/* 671/*
668 * instantiate an rxrpc defined key 672 * Preparse an rxrpc defined key.
669 * data should be of the form: 673 *
674 * Data should be of the form:
670 * OFFSET LEN CONTENT 675 * OFFSET LEN CONTENT
671 * 0 4 key interface version number 676 * 0 4 key interface version number
672 * 4 2 security index (type) 677 * 4 2 security index (type)
@@ -678,7 +683,7 @@ error:
678 * 683 *
679 * if no data is provided, then a no-security key is made 684 * if no data is provided, then a no-security key is made
680 */ 685 */
681static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) 686static int rxrpc_preparse(struct key_preparsed_payload *prep)
682{ 687{
683 const struct rxrpc_key_data_v1 *v1; 688 const struct rxrpc_key_data_v1 *v1;
684 struct rxrpc_key_token *token, **pp; 689 struct rxrpc_key_token *token, **pp;
@@ -686,7 +691,7 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
686 u32 kver; 691 u32 kver;
687 int ret; 692 int ret;
688 693
689 _enter("{%x},,%zu", key_serial(key), prep->datalen); 694 _enter("%zu", prep->datalen);
690 695
691 /* handle a no-security key */ 696 /* handle a no-security key */
692 if (!prep->data && prep->datalen == 0) 697 if (!prep->data && prep->datalen == 0)
@@ -694,7 +699,7 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
694 699
695 /* determine if the XDR payload format is being used */ 700 /* determine if the XDR payload format is being used */
696 if (prep->datalen > 7 * 4) { 701 if (prep->datalen > 7 * 4) {
697 ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); 702 ret = rxrpc_preparse_xdr(prep);
698 if (ret != -EPROTO) 703 if (ret != -EPROTO)
699 return ret; 704 return ret;
700 } 705 }
@@ -743,9 +748,7 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
743 goto error; 748 goto error;
744 749
745 plen = sizeof(*token->kad) + v1->ticket_length; 750 plen = sizeof(*token->kad) + v1->ticket_length;
746 ret = key_payload_reserve(key, plen + sizeof(*token)); 751 prep->quotalen = plen + sizeof(*token);
747 if (ret < 0)
748 goto error;
749 752
750 ret = -ENOMEM; 753 ret = -ENOMEM;
751 token = kzalloc(sizeof(*token), GFP_KERNEL); 754 token = kzalloc(sizeof(*token), GFP_KERNEL);
@@ -762,15 +765,16 @@ static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep
762 memcpy(&token->kad->session_key, &v1->session_key, 8); 765 memcpy(&token->kad->session_key, &v1->session_key, 8);
763 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 766 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
764 767
765 /* attach the data */ 768 /* count the number of tokens attached */
766 key->type_data.x[0]++; 769 prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1);
767 770
768 pp = (struct rxrpc_key_token **)&key->payload.data; 771 /* attach the data */
772 pp = (struct rxrpc_key_token **)&prep->payload[0];
769 while (*pp) 773 while (*pp)
770 pp = &(*pp)->next; 774 pp = &(*pp)->next;
771 *pp = token; 775 *pp = token;
772 if (token->kad->expiry < key->expiry) 776 if (token->kad->expiry < prep->expiry)
773 key->expiry = token->kad->expiry; 777 prep->expiry = token->kad->expiry;
774 token = NULL; 778 token = NULL;
775 ret = 0; 779 ret = 0;
776 780
@@ -781,20 +785,55 @@ error:
781} 785}
782 786
783/* 787/*
784 * instantiate a server secret key 788 * Free token list.
785 * data should be a pointer to the 8-byte secret key
786 */ 789 */
787static int rxrpc_instantiate_s(struct key *key, 790static void rxrpc_free_token_list(struct rxrpc_key_token *token)
788 struct key_preparsed_payload *prep) 791{
792 struct rxrpc_key_token *next;
793
794 for (; token; token = next) {
795 next = token->next;
796 switch (token->security_index) {
797 case RXRPC_SECURITY_RXKAD:
798 kfree(token->kad);
799 break;
800 case RXRPC_SECURITY_RXK5:
801 if (token->k5)
802 rxrpc_rxk5_free(token->k5);
803 break;
804 default:
805 printk(KERN_ERR "Unknown token type %x on rxrpc key\n",
806 token->security_index);
807 BUG();
808 }
809
810 kfree(token);
811 }
812}
813
814/*
815 * Clean up preparse data.
816 */
817static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
818{
819 rxrpc_free_token_list(prep->payload[0]);
820}
821
822/*
823 * Preparse a server secret key.
824 *
825 * The data should be the 8-byte secret key.
826 */
827static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
789{ 828{
790 struct crypto_blkcipher *ci; 829 struct crypto_blkcipher *ci;
791 830
792 _enter("{%x},,%zu", key_serial(key), prep->datalen); 831 _enter("%zu", prep->datalen);
793 832
794 if (prep->datalen != 8) 833 if (prep->datalen != 8)
795 return -EINVAL; 834 return -EINVAL;
796 835
797 memcpy(&key->type_data, prep->data, 8); 836 memcpy(&prep->type_data, prep->data, 8);
798 837
799 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 838 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
800 if (IS_ERR(ci)) { 839 if (IS_ERR(ci)) {
@@ -805,36 +844,26 @@ static int rxrpc_instantiate_s(struct key *key,
805 if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) 844 if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
806 BUG(); 845 BUG();
807 846
808 key->payload.data = ci; 847 prep->payload[0] = ci;
809 _leave(" = 0"); 848 _leave(" = 0");
810 return 0; 849 return 0;
811} 850}
812 851
813/* 852/*
853 * Clean up preparse data.
854 */
855static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
856{
857 if (prep->payload[0])
858 crypto_free_blkcipher(prep->payload[0]);
859}
860
861/*
814 * dispose of the data dangling from the corpse of a rxrpc key 862 * dispose of the data dangling from the corpse of a rxrpc key
815 */ 863 */
816static void rxrpc_destroy(struct key *key) 864static void rxrpc_destroy(struct key *key)
817{ 865{
818 struct rxrpc_key_token *token; 866 rxrpc_free_token_list(key->payload.data);
819
820 while ((token = key->payload.data)) {
821 key->payload.data = token->next;
822 switch (token->security_index) {
823 case RXRPC_SECURITY_RXKAD:
824 kfree(token->kad);
825 break;
826 case RXRPC_SECURITY_RXK5:
827 if (token->k5)
828 rxrpc_rxk5_free(token->k5);
829 break;
830 default:
831 printk(KERN_ERR "Unknown token type %x on rxrpc key\n",
832 token->security_index);
833 BUG();
834 }
835
836 kfree(token);
837 }
838} 867}
839 868
840/* 869/*
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 8137b27d641d..c2f91a0cf889 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -34,7 +34,9 @@ MODULE_LICENSE("GPL");
34struct key_type key_type_big_key = { 34struct key_type key_type_big_key = {
35 .name = "big_key", 35 .name = "big_key",
36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
37 .instantiate = big_key_instantiate, 37 .preparse = big_key_preparse,
38 .free_preparse = big_key_free_preparse,
39 .instantiate = generic_key_instantiate,
38 .match = user_match, 40 .match = user_match,
39 .revoke = big_key_revoke, 41 .revoke = big_key_revoke,
40 .destroy = big_key_destroy, 42 .destroy = big_key_destroy,
@@ -43,11 +45,11 @@ struct key_type key_type_big_key = {
43}; 45};
44 46
45/* 47/*
46 * Instantiate a big key 48 * Preparse a big key
47 */ 49 */
48int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 50int big_key_preparse(struct key_preparsed_payload *prep)
49{ 51{
50 struct path *path = (struct path *)&key->payload.data2; 52 struct path *path = (struct path *)&prep->payload;
51 struct file *file; 53 struct file *file;
52 ssize_t written; 54 ssize_t written;
53 size_t datalen = prep->datalen; 55 size_t datalen = prep->datalen;
@@ -58,11 +60,9 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
58 goto error; 60 goto error;
59 61
60 /* Set an arbitrary quota */ 62 /* Set an arbitrary quota */
61 ret = key_payload_reserve(key, 16); 63 prep->quotalen = 16;
62 if (ret < 0)
63 goto error;
64 64
65 key->type_data.x[1] = datalen; 65 prep->type_data[1] = (void *)(unsigned long)datalen;
66 66
67 if (datalen > BIG_KEY_FILE_THRESHOLD) { 67 if (datalen > BIG_KEY_FILE_THRESHOLD) {
68 /* Create a shmem file to store the data in. This will permit the data 68 /* Create a shmem file to store the data in. This will permit the data
@@ -73,7 +73,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
73 file = shmem_kernel_file_setup("", datalen, 0); 73 file = shmem_kernel_file_setup("", datalen, 0);
74 if (IS_ERR(file)) { 74 if (IS_ERR(file)) {
75 ret = PTR_ERR(file); 75 ret = PTR_ERR(file);
76 goto err_quota; 76 goto error;
77 } 77 }
78 78
79 written = kernel_write(file, prep->data, prep->datalen, 0); 79 written = kernel_write(file, prep->data, prep->datalen, 0);
@@ -93,24 +93,33 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
93 } else { 93 } else {
94 /* Just store the data in a buffer */ 94 /* Just store the data in a buffer */
95 void *data = kmalloc(datalen, GFP_KERNEL); 95 void *data = kmalloc(datalen, GFP_KERNEL);
96 if (!data) { 96 if (!data)
97 ret = -ENOMEM; 97 return -ENOMEM;
98 goto err_quota;
99 }
100 98
101 key->payload.data = memcpy(data, prep->data, prep->datalen); 99 prep->payload[0] = memcpy(data, prep->data, prep->datalen);
102 } 100 }
103 return 0; 101 return 0;
104 102
105err_fput: 103err_fput:
106 fput(file); 104 fput(file);
107err_quota:
108 key_payload_reserve(key, 0);
109error: 105error:
110 return ret; 106 return ret;
111} 107}
112 108
113/* 109/*
110 * Clear preparsement.
111 */
112void big_key_free_preparse(struct key_preparsed_payload *prep)
113{
114 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
115 struct path *path = (struct path *)&prep->payload;
116 path_put(path);
117 } else {
118 kfree(prep->payload[0]);
119 }
120}
121
122/*
114 * dispose of the links from a revoked keyring 123 * dispose of the links from a revoked keyring
115 * - called with the key sem write-locked 124 * - called with the key sem write-locked
116 */ 125 */
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 5fe443d120af..d252c5704f8a 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -811,7 +811,7 @@ static int encrypted_instantiate(struct key *key,
811 goto out; 811 goto out;
812 } 812 }
813 813
814 rcu_assign_keypointer(key, epayload); 814 prep->payload[0] = epayload;
815out: 815out:
816 kfree(datablob); 816 kfree(datablob);
817 return ret; 817 return ret;
diff --git a/security/keys/key.c b/security/keys/key.c
index 2048a110e7f1..b90a68c4e2c4 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -437,6 +437,11 @@ static int __key_instantiate_and_link(struct key *key,
437 /* disable the authorisation key */ 437 /* disable the authorisation key */
438 if (authkey) 438 if (authkey)
439 key_revoke(authkey); 439 key_revoke(authkey);
440
441 if (prep->expiry != TIME_T_MAX) {
442 key->expiry = prep->expiry;
443 key_schedule_gc(prep->expiry + key_gc_delay);
444 }
440 } 445 }
441 } 446 }
442 447
@@ -479,6 +484,7 @@ int key_instantiate_and_link(struct key *key,
479 prep.data = data; 484 prep.data = data;
480 prep.datalen = datalen; 485 prep.datalen = datalen;
481 prep.quotalen = key->type->def_datalen; 486 prep.quotalen = key->type->def_datalen;
487 prep.expiry = TIME_T_MAX;
482 if (key->type->preparse) { 488 if (key->type->preparse) {
483 ret = key->type->preparse(&prep); 489 ret = key->type->preparse(&prep);
484 if (ret < 0) 490 if (ret < 0)
@@ -488,7 +494,7 @@ int key_instantiate_and_link(struct key *key,
488 if (keyring) { 494 if (keyring) {
489 ret = __key_link_begin(keyring, &key->index_key, &edit); 495 ret = __key_link_begin(keyring, &key->index_key, &edit);
490 if (ret < 0) 496 if (ret < 0)
491 goto error_free_preparse; 497 goto error;
492 } 498 }
493 499
494 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit); 500 ret = __key_instantiate_and_link(key, &prep, keyring, authkey, &edit);
@@ -496,10 +502,9 @@ int key_instantiate_and_link(struct key *key,
496 if (keyring) 502 if (keyring)
497 __key_link_end(keyring, &key->index_key, edit); 503 __key_link_end(keyring, &key->index_key, edit);
498 504
499error_free_preparse: 505error:
500 if (key->type->preparse) 506 if (key->type->preparse)
501 key->type->free_preparse(&prep); 507 key->type->free_preparse(&prep);
502error:
503 return ret; 508 return ret;
504} 509}
505 510
@@ -811,11 +816,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 prep.datalen = plen; 816 prep.datalen = plen;
812 prep.quotalen = index_key.type->def_datalen; 817 prep.quotalen = index_key.type->def_datalen;
813 prep.trusted = flags & KEY_ALLOC_TRUSTED; 818 prep.trusted = flags & KEY_ALLOC_TRUSTED;
819 prep.expiry = TIME_T_MAX;
814 if (index_key.type->preparse) { 820 if (index_key.type->preparse) {
815 ret = index_key.type->preparse(&prep); 821 ret = index_key.type->preparse(&prep);
816 if (ret < 0) { 822 if (ret < 0) {
817 key_ref = ERR_PTR(ret); 823 key_ref = ERR_PTR(ret);
818 goto error_put_type; 824 goto error_free_prep;
819 } 825 }
820 if (!index_key.description) 826 if (!index_key.description)
821 index_key.description = prep.description; 827 index_key.description = prep.description;
@@ -941,6 +947,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
941 prep.data = payload; 947 prep.data = payload;
942 prep.datalen = plen; 948 prep.datalen = plen;
943 prep.quotalen = key->type->def_datalen; 949 prep.quotalen = key->type->def_datalen;
950 prep.expiry = TIME_T_MAX;
944 if (key->type->preparse) { 951 if (key->type->preparse) {
945 ret = key->type->preparse(&prep); 952 ret = key->type->preparse(&prep);
946 if (ret < 0) 953 if (ret < 0)
@@ -956,9 +963,9 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
956 963
957 up_write(&key->sem); 964 up_write(&key->sem);
958 965
966error:
959 if (key->type->preparse) 967 if (key->type->preparse)
960 key->type->free_preparse(&prep); 968 key->type->free_preparse(&prep);
961error:
962 return ret; 969 return ret;
963} 970}
964EXPORT_SYMBOL(key_update); 971EXPORT_SYMBOL(key_update);
@@ -1024,6 +1031,38 @@ void key_invalidate(struct key *key)
1024EXPORT_SYMBOL(key_invalidate); 1031EXPORT_SYMBOL(key_invalidate);
1025 1032
1026/** 1033/**
1034 * generic_key_instantiate - Simple instantiation of a key from preparsed data
1035 * @key: The key to be instantiated
1036 * @prep: The preparsed data to load.
1037 *
1038 * Instantiate a key from preparsed data. We assume we can just copy the data
1039 * in directly and clear the old pointers.
1040 *
1041 * This can be pointed to directly by the key type instantiate op pointer.
1042 */
1043int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
1044{
1045 int ret;
1046
1047 pr_devel("==>%s()\n", __func__);
1048
1049 ret = key_payload_reserve(key, prep->quotalen);
1050 if (ret == 0) {
1051 key->type_data.p[0] = prep->type_data[0];
1052 key->type_data.p[1] = prep->type_data[1];
1053 rcu_assign_keypointer(key, prep->payload[0]);
1054 key->payload.data2[1] = prep->payload[1];
1055 prep->type_data[0] = NULL;
1056 prep->type_data[1] = NULL;
1057 prep->payload[0] = NULL;
1058 prep->payload[1] = NULL;
1059 }
1060 pr_devel("<==%s() = %d\n", __func__, ret);
1061 return ret;
1062}
1063EXPORT_SYMBOL(generic_key_instantiate);
1064
1065/**
1027 * register_key_type - Register a type of key. 1066 * register_key_type - Register a type of key.
1028 * @ktype: The new key type. 1067 * @ktype: The new key type.
1029 * 1068 *
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 9cf2575f0d97..8314a7d2104d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -73,6 +73,8 @@ static inline unsigned keyring_hash(const char *desc)
73 * can be treated as ordinary keys in addition to having their own special 73 * can be treated as ordinary keys in addition to having their own special
74 * operations. 74 * operations.
75 */ 75 */
76static int keyring_preparse(struct key_preparsed_payload *prep);
77static void keyring_free_preparse(struct key_preparsed_payload *prep);
76static int keyring_instantiate(struct key *keyring, 78static int keyring_instantiate(struct key *keyring,
77 struct key_preparsed_payload *prep); 79 struct key_preparsed_payload *prep);
78static void keyring_revoke(struct key *keyring); 80static void keyring_revoke(struct key *keyring);
@@ -84,6 +86,8 @@ static long keyring_read(const struct key *keyring,
84struct key_type key_type_keyring = { 86struct key_type key_type_keyring = {
85 .name = "keyring", 87 .name = "keyring",
86 .def_datalen = 0, 88 .def_datalen = 0,
89 .preparse = keyring_preparse,
90 .free_preparse = keyring_free_preparse,
87 .instantiate = keyring_instantiate, 91 .instantiate = keyring_instantiate,
88 .match = user_match, 92 .match = user_match,
89 .revoke = keyring_revoke, 93 .revoke = keyring_revoke,
@@ -123,6 +127,21 @@ static void keyring_publish_name(struct key *keyring)
123} 127}
124 128
125/* 129/*
130 * Preparse a keyring payload
131 */
132static int keyring_preparse(struct key_preparsed_payload *prep)
133{
134 return prep->datalen != 0 ? -EINVAL : 0;
135}
136
137/*
138 * Free a preparse of a user defined key payload
139 */
140static void keyring_free_preparse(struct key_preparsed_payload *prep)
141{
142}
143
144/*
126 * Initialise a keyring. 145 * Initialise a keyring.
127 * 146 *
128 * Returns 0 on success, -EINVAL if given any data. 147 * Returns 0 on success, -EINVAL if given any data.
@@ -130,17 +149,10 @@ static void keyring_publish_name(struct key *keyring)
130static int keyring_instantiate(struct key *keyring, 149static int keyring_instantiate(struct key *keyring,
131 struct key_preparsed_payload *prep) 150 struct key_preparsed_payload *prep)
132{ 151{
133 int ret; 152 assoc_array_init(&keyring->keys);
134 153 /* make the keyring available by name if it has one */
135 ret = -EINVAL; 154 keyring_publish_name(keyring);
136 if (prep->datalen == 0) { 155 return 0;
137 assoc_array_init(&keyring->keys);
138 /* make the keyring available by name if it has one */
139 keyring_publish_name(keyring);
140 ret = 0;
141 }
142
143 return ret;
144} 156}
145 157
146/* 158/*
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 7495a93b4b90..842e6f410d50 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -20,6 +20,8 @@
20#include "internal.h" 20#include "internal.h"
21#include <keys/user-type.h> 21#include <keys/user-type.h>
22 22
23static int request_key_auth_preparse(struct key_preparsed_payload *);
24static void request_key_auth_free_preparse(struct key_preparsed_payload *);
23static int request_key_auth_instantiate(struct key *, 25static int request_key_auth_instantiate(struct key *,
24 struct key_preparsed_payload *); 26 struct key_preparsed_payload *);
25static void request_key_auth_describe(const struct key *, struct seq_file *); 27static void request_key_auth_describe(const struct key *, struct seq_file *);
@@ -33,6 +35,8 @@ static long request_key_auth_read(const struct key *, char __user *, size_t);
33struct key_type key_type_request_key_auth = { 35struct key_type key_type_request_key_auth = {
34 .name = ".request_key_auth", 36 .name = ".request_key_auth",
35 .def_datalen = sizeof(struct request_key_auth), 37 .def_datalen = sizeof(struct request_key_auth),
38 .preparse = request_key_auth_preparse,
39 .free_preparse = request_key_auth_free_preparse,
36 .instantiate = request_key_auth_instantiate, 40 .instantiate = request_key_auth_instantiate,
37 .describe = request_key_auth_describe, 41 .describe = request_key_auth_describe,
38 .revoke = request_key_auth_revoke, 42 .revoke = request_key_auth_revoke,
@@ -40,6 +44,15 @@ struct key_type key_type_request_key_auth = {
40 .read = request_key_auth_read, 44 .read = request_key_auth_read,
41}; 45};
42 46
47int request_key_auth_preparse(struct key_preparsed_payload *prep)
48{
49 return 0;
50}
51
52void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
53{
54}
55
43/* 56/*
44 * Instantiate a request-key authorisation key. 57 * Instantiate a request-key authorisation key.
45 */ 58 */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index faa2caeb593f..eee340011f2b 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -27,7 +27,9 @@ static int logon_vet_description(const char *desc);
27struct key_type key_type_user = { 27struct key_type key_type_user = {
28 .name = "user", 28 .name = "user",
29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
30 .instantiate = user_instantiate, 30 .preparse = user_preparse,
31 .free_preparse = user_free_preparse,
32 .instantiate = generic_key_instantiate,
31 .update = user_update, 33 .update = user_update,
32 .match = user_match, 34 .match = user_match,
33 .revoke = user_revoke, 35 .revoke = user_revoke,
@@ -47,7 +49,9 @@ EXPORT_SYMBOL_GPL(key_type_user);
47struct key_type key_type_logon = { 49struct key_type key_type_logon = {
48 .name = "logon", 50 .name = "logon",
49 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 51 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
50 .instantiate = user_instantiate, 52 .preparse = user_preparse,
53 .free_preparse = user_free_preparse,
54 .instantiate = generic_key_instantiate,
51 .update = user_update, 55 .update = user_update,
52 .match = user_match, 56 .match = user_match,
53 .revoke = user_revoke, 57 .revoke = user_revoke,
@@ -58,38 +62,37 @@ struct key_type key_type_logon = {
58EXPORT_SYMBOL_GPL(key_type_logon); 62EXPORT_SYMBOL_GPL(key_type_logon);
59 63
60/* 64/*
61 * instantiate a user defined key 65 * Preparse a user defined key payload
62 */ 66 */
63int user_instantiate(struct key *key, struct key_preparsed_payload *prep) 67int user_preparse(struct key_preparsed_payload *prep)
64{ 68{
65 struct user_key_payload *upayload; 69 struct user_key_payload *upayload;
66 size_t datalen = prep->datalen; 70 size_t datalen = prep->datalen;
67 int ret;
68 71
69 ret = -EINVAL;
70 if (datalen <= 0 || datalen > 32767 || !prep->data) 72 if (datalen <= 0 || datalen > 32767 || !prep->data)
71 goto error; 73 return -EINVAL;
72
73 ret = key_payload_reserve(key, datalen);
74 if (ret < 0)
75 goto error;
76 74
77 ret = -ENOMEM;
78 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); 75 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
79 if (!upayload) 76 if (!upayload)
80 goto error; 77 return -ENOMEM;
81 78
82 /* attach the data */ 79 /* attach the data */
80 prep->quotalen = datalen;
81 prep->payload[0] = upayload;
83 upayload->datalen = datalen; 82 upayload->datalen = datalen;
84 memcpy(upayload->data, prep->data, datalen); 83 memcpy(upayload->data, prep->data, datalen);
85 rcu_assign_keypointer(key, upayload); 84 return 0;
86 ret = 0;
87
88error:
89 return ret;
90} 85}
86EXPORT_SYMBOL_GPL(user_preparse);
91 87
92EXPORT_SYMBOL_GPL(user_instantiate); 88/*
89 * Free a preparse of a user defined key payload
90 */
91void user_free_preparse(struct key_preparsed_payload *prep)
92{
93 kfree(prep->payload[0]);
94}
95EXPORT_SYMBOL_GPL(user_free_preparse);
93 96
94/* 97/*
95 * update a user defined key 98 * update a user defined key