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