diff options
| author | David Howells <dhowells@redhat.com> | 2012-10-02 14:30:19 -0400 |
|---|---|---|
| committer | David Howells <dhowells@redhat.com> | 2012-10-02 14:30:19 -0400 |
| commit | 4442d7704c7311d1c42383d365e0b883e0075975 (patch) | |
| tree | ee80c095ea8b13c2ad62c9406ddc6166c5b09cb4 | |
| parent | f8aa23a55f813c9bddec2a6176e0e67274e6e7c1 (diff) | |
| parent | d4f65b5d2497b2fd9c45f06b71deb4ab084a5b66 (diff) | |
Merge branch 'modsign-keys-devel' into security-next-keys
Signed-off-by: David Howells <dhowells@redhat.com>
| -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 a4f9125c033..7b4145d0045 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. |
| @@ -1131,12 +1135,53 @@ The structure has a number of fields, some of which are mandatory: | |||
| 1131 | it should return 0. | 1135 | it should return 0. |
| 1132 | 1136 | ||
| 1133 | 1137 | ||
| 1134 | (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); | 1138 | (*) int (*preparse)(struct key_preparsed_payload *prep); |
| 1139 | |||
| 1140 | This optional method permits the key type to attempt to parse payload | ||
| 1141 | before a key is created (add key) or the key semaphore is taken (update or | ||
| 1142 | instantiate key). The structure pointed to by prep looks like: | ||
| 1143 | |||
| 1144 | struct key_preparsed_payload { | ||
| 1145 | char *description; | ||
| 1146 | void *type_data[2]; | ||
| 1147 | void *payload; | ||
| 1148 | const void *data; | ||
| 1149 | size_t datalen; | ||
| 1150 | size_t quotalen; | ||
| 1151 | }; | ||
| 1152 | |||
| 1153 | Before calling the method, the caller will fill in data and datalen with | ||
| 1154 | the payload blob parameters; quotalen will be filled in with the default | ||
| 1155 | quota size from the key type and the rest will be cleared. | ||
| 1156 | |||
| 1157 | If a description can be proposed from the payload contents, that should be | ||
| 1158 | attached as a string to the description field. This will be used for the | ||
| 1159 | key description if the caller of add_key() passes NULL or "". | ||
| 1160 | |||
| 1161 | The method can attach anything it likes to type_data[] and payload. These | ||
| 1162 | are merely passed along to the instantiate() or update() operations. | ||
| 1163 | |||
| 1164 | The method should return 0 if success ful or a negative error code | ||
| 1165 | otherwise. | ||
| 1166 | |||
| 1167 | |||
| 1168 | (*) void (*free_preparse)(struct key_preparsed_payload *prep); | ||
| 1169 | |||
| 1170 | This method is only required if the preparse() method is provided, | ||
| 1171 | otherwise it is unused. It cleans up anything attached to the | ||
| 1172 | description, type_data and payload fields of the key_preparsed_payload | ||
| 1173 | struct as filled in by the preparse() method. | ||
| 1174 | |||
| 1175 | |||
| 1176 | (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); | ||
| 1135 | 1177 | ||
| 1136 | This method is called to attach a payload to a key during construction. | 1178 | This method is called to attach a payload to a key during construction. |
| 1137 | The payload attached need not bear any relation to the data passed to this | 1179 | The payload attached need not bear any relation to the data passed to this |
| 1138 | function. | 1180 | function. |
| 1139 | 1181 | ||
| 1182 | The prep->data and prep->datalen fields will define the original payload | ||
| 1183 | blob. If preparse() was supplied then other fields may be filled in also. | ||
| 1184 | |||
| 1140 | If the amount of data attached to the key differs from the size in | 1185 | If the amount of data attached to the key differs from the size in |
| 1141 | keytype->def_datalen, then key_payload_reserve() should be called. | 1186 | keytype->def_datalen, then key_payload_reserve() should be called. |
| 1142 | 1187 | ||
| @@ -1152,6 +1197,9 @@ The structure has a number of fields, some of which are mandatory: | |||
| 1152 | If this type of key can be updated, then this method should be provided. | 1197 | If this type of key can be updated, then this method should be provided. |
| 1153 | It is called to update a key's payload from the blob of data provided. | 1198 | It is called to update a key's payload from the blob of data provided. |
| 1154 | 1199 | ||
| 1200 | The prep->data and prep->datalen fields will define the original payload | ||
| 1201 | blob. If preparse() was supplied then other fields may be filled in also. | ||
| 1202 | |||
| 1155 | key_payload_reserve() should be called if the data length might change | 1203 | key_payload_reserve() should be called if the data length might change |
| 1156 | before any changes are actually made. Note that if this succeeds, the type | 1204 | before any changes are actually made. Note that if this succeeds, the type |
| 1157 | is committed to changing the key because it's already been altered, so all | 1205 | 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 e622863b292..086f381d648 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 a8a753c8fcd..3151a264988 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 bc9ec1d7698..5e452c84f1e 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 f0c651cda7b..518a53afb9e 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 9da7fdd3cd8..af14cb42516 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 f2c379d835e..b53bb4a41da 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 8b1f9f49960..106c5a6b1ab 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 2d1bb8af769..9e1e005c759 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 bebeca3a78e..da63a659db7 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 65b38417c21..6d9d0c74752 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 8c25558da14..9270ba054a1 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 60d4e3f5e4b..85730d5a5a5 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 3f163d0489a..e13fcf7636f 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
| @@ -895,23 +895,24 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key) | |||
| 895 | * | 895 | * |
| 896 | * On success, return 0. Otherwise return errno. | 896 | * On success, return 0. Otherwise return errno. |
| 897 | */ | 897 | */ |
| 898 | static int trusted_instantiate(struct key *key, const void *data, | 898 | static int trusted_instantiate(struct key *key, |
| 899 | size_t datalen) | 899 | struct key_preparsed_payload *prep) |
| 900 | { | 900 | { |
| 901 | struct trusted_key_payload *payload = NULL; | 901 | struct trusted_key_payload *payload = NULL; |
| 902 | struct trusted_key_options *options = NULL; | 902 | struct trusted_key_options *options = NULL; |
| 903 | size_t datalen = prep->datalen; | ||
| 903 | char *datablob; | 904 | char *datablob; |
| 904 | int ret = 0; | 905 | int ret = 0; |
| 905 | int key_cmd; | 906 | int key_cmd; |
| 906 | size_t key_len; | 907 | size_t key_len; |
| 907 | 908 | ||
| 908 | if (datalen <= 0 || datalen > 32767 || !data) | 909 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 909 | return -EINVAL; | 910 | return -EINVAL; |
| 910 | 911 | ||
| 911 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 912 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
| 912 | if (!datablob) | 913 | if (!datablob) |
| 913 | return -ENOMEM; | 914 | return -ENOMEM; |
| 914 | memcpy(datablob, data, datalen); | 915 | memcpy(datablob, prep->data, datalen); |
| 915 | datablob[datalen] = '\0'; | 916 | datablob[datalen] = '\0'; |
| 916 | 917 | ||
| 917 | options = trusted_options_alloc(); | 918 | options = trusted_options_alloc(); |
| @@ -981,17 +982,18 @@ static void trusted_rcu_free(struct rcu_head *rcu) | |||
| 981 | /* | 982 | /* |
| 982 | * trusted_update - reseal an existing key with new PCR values | 983 | * trusted_update - reseal an existing key with new PCR values |
| 983 | */ | 984 | */ |
| 984 | static int trusted_update(struct key *key, const void *data, size_t datalen) | 985 | static int trusted_update(struct key *key, struct key_preparsed_payload *prep) |
| 985 | { | 986 | { |
| 986 | struct trusted_key_payload *p = key->payload.data; | 987 | struct trusted_key_payload *p = key->payload.data; |
| 987 | struct trusted_key_payload *new_p; | 988 | struct trusted_key_payload *new_p; |
| 988 | struct trusted_key_options *new_o; | 989 | struct trusted_key_options *new_o; |
| 990 | size_t datalen = prep->datalen; | ||
| 989 | char *datablob; | 991 | char *datablob; |
| 990 | int ret = 0; | 992 | int ret = 0; |
| 991 | 993 | ||
| 992 | if (!p->migratable) | 994 | if (!p->migratable) |
| 993 | return -EPERM; | 995 | return -EPERM; |
| 994 | if (datalen <= 0 || datalen > 32767 || !data) | 996 | if (datalen <= 0 || datalen > 32767 || !prep->data) |
| 995 | return -EINVAL; | 997 | return -EINVAL; |
| 996 | 998 | ||
| 997 | datablob = kmalloc(datalen + 1, GFP_KERNEL); | 999 | datablob = kmalloc(datalen + 1, GFP_KERNEL); |
| @@ -1008,7 +1010,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen) | |||
| 1008 | goto out; | 1010 | goto out; |
| 1009 | } | 1011 | } |
| 1010 | 1012 | ||
| 1011 | memcpy(datablob, data, datalen); | 1013 | memcpy(datablob, prep->data, datalen); |
| 1012 | datablob[datalen] = '\0'; | 1014 | datablob[datalen] = '\0'; |
| 1013 | ret = datablob_parse(datablob, new_p, new_o); | 1015 | ret = datablob_parse(datablob, new_p, new_o); |
| 1014 | if (ret != Opt_update) { | 1016 | if (ret != Opt_update) { |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index c7660a25a3e..55dc8893918 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; |
