diff --git a/kernel.spec b/kernel.spec index 16d90a8d7..05f65d2c0 100644 --- a/kernel.spec +++ b/kernel.spec @@ -62,7 +62,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 2 +%global baserelease 1 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -95,7 +95,7 @@ Summary: The Linux kernel # The rc snapshot level %define rcrev 2 # The git snapshot level -%define gitrev 0 +%define gitrev 1 # Set rpm version accordingly %define rpmversion 3.%{upstream_sublevel}.0 %endif @@ -678,7 +678,7 @@ Patch700: linux-2.6-e1000-ich9-montevina.patch Patch800: linux-2.6-crash-driver.patch # crypto/ -Patch900: modsign-20120814.patch +Patch900: modsign-20120816.patch # secure boot Patch1000: secure-boot-20120809.patch @@ -747,9 +747,6 @@ Patch22001: selinux-apply-different-permission-to-ptrace-child.patch #rhbz 836742 Patch22059: uvcvideo-Reset-bytesused-field-when-recycling-erroneous-buffer.patch -#rhbz 844485 -Patch22060: vfs-fix-file-creation-bugs.patch - # END OF PATCH DEFINITIONS %endif @@ -1382,7 +1379,7 @@ ApplyPatch linux-2.6-crash-driver.patch ApplyPatch linux-2.6-e1000-ich9-montevina.patch # crypto/ -ApplyPatch modsign-20120814.patch +ApplyPatch modsign-20120816.patch # secure boot ApplyPatch secure-boot-20120809.patch @@ -1440,9 +1437,6 @@ ApplyPatch selinux-apply-different-permission-to-ptrace-child.patch #rhbz 836742 ApplyPatch uvcvideo-Reset-bytesused-field-when-recycling-erroneous-buffer.patch -#rhbz 844485 -ApplyPatch vfs-fix-file-creation-bugs.patch - # END OF PATCH APPLICATIONS %endif @@ -2305,6 +2299,9 @@ fi # ||----w | # || || %changelog +* Mon Aug 20 2012 Josh Boyer - 3.6.0-0.rc2.git1.1 +- Linux v3.6-rc2-206-g10c63c9 + * Mon Aug 20 2012 Dave Jones - Reenable W1 drivers. (rhbz 849430) diff --git a/modsign-20120814.patch b/modsign-20120816.patch similarity index 79% rename from modsign-20120814.patch rename to modsign-20120816.patch index deb6ccb98..886e313c8 100644 --- a/modsign-20120814.patch +++ b/modsign-20120816.patch @@ -1,7 +1,963 @@ -From 711fd460b3d44d666fbddd80a91ae5f825c7ebb6 Mon Sep 17 00:00:00 2001 +From bcb9a5e7e8108872ec9fd7083209cbf3a47ef952 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 13:59:15 +0100 -Subject: [PATCH 01/28] MPILIB: Provide count_leading/trailing_zeros() based +Date: Thu, 16 Aug 2012 00:14:14 +0100 +Subject: [PATCH 01/32] KEYS: Add payload preparsing opportunity prior to key + instantiate or update + +Give the key type the opportunity to preparse the payload prior to the +instantiation and update routines being called. This is done with the +provision of two new key type operations: + + int (*preparse)(struct key_preparsed_payload *prep); + void (*free_preparse)(struct key_preparsed_payload *prep); + +If the first operation is present, then it is called before key creation (in +the add/update case) or before the key semaphore is taken (in the update and +instantiate cases). The second operation is called to clean up if the first +was called. + +preparse() is given the opportunity to fill in the following structure: + + struct key_preparsed_payload { + char *description; + void *type_data[2]; + void *payload; + const void *data; + size_t datalen; + size_t quotalen; + }; + +Before the preparser is called, the first three fields will have been cleared, +the payload pointer and size will be stored in data and datalen and the default +quota size from the key_type struct will be stored into quotalen. + +The preparser may parse the payload in any way it likes and may store data in +the type_data[] and payload fields for use by the instantiate() and update() +ops. + +The preparser may also propose a description for the key by attaching it as a +string to the description field. This can be used by passing a NULL or "" +description to the add_key() system call or the key_create_or_update() +function. This cannot work with request_key() as that required the description +to tell the upcall about the key to be created. + +This, for example permits keys that store PGP public keys to generate their own +name from the user ID and public key fingerprint in the key. + +The instantiate() and update() operations are then modified to look like this: + + int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); + int (*update)(struct key *key, struct key_preparsed_payload *prep); + +and the new payload data is passed in *prep, whether or not it was preparsed. + +Signed-off-by: David Howells +--- + Documentation/security/keys.txt | 50 +++++++++++++- + fs/cifs/cifs_spnego.c | 6 +- + fs/cifs/cifsacl.c | 8 +-- + include/keys/user-type.h | 6 +- + include/linux/key-type.h | 35 +++++++++- + net/ceph/crypto.c | 9 +-- + net/dns_resolver/dns_key.c | 6 +- + net/rxrpc/ar-key.c | 40 ++++++------ + security/keys/encrypted-keys/encrypted.c | 16 +++-- + security/keys/key.c | 108 ++++++++++++++++++++++--------- + security/keys/keyctl.c | 18 ++++-- + security/keys/keyring.c | 6 +- + security/keys/request_key_auth.c | 8 +-- + security/keys/trusted.c | 16 +++-- + security/keys/user_defined.c | 14 ++-- + 15 files changed, 245 insertions(+), 101 deletions(-) + +diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt +index aa0dbd7..7d9ca92 100644 +--- a/Documentation/security/keys.txt ++++ b/Documentation/security/keys.txt +@@ -412,6 +412,10 @@ The main syscalls are: + to the keyring. In this case, an error will be generated if the process + does not have permission to write to the keyring. + ++ If the key type supports it, if the description is NULL or an empty ++ string, the key type will try and generate a description from the content ++ of the payload. ++ + The payload is optional, and the pointer can be NULL if not required by + the type. The payload is plen in size, and plen can be zero for an empty + payload. +@@ -1114,12 +1118,53 @@ The structure has a number of fields, some of which are mandatory: + it should return 0. + + +- (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); ++ (*) int (*preparse)(struct key_preparsed_payload *prep); ++ ++ This optional method permits the key type to attempt to parse payload ++ before a key is created (add key) or the key semaphore is taken (update or ++ instantiate key). The structure pointed to by prep looks like: ++ ++ struct key_preparsed_payload { ++ char *description; ++ void *type_data[2]; ++ void *payload; ++ const void *data; ++ size_t datalen; ++ size_t quotalen; ++ }; ++ ++ Before calling the method, the caller will fill in data and datalen with ++ the payload blob parameters; quotalen will be filled in with the default ++ quota size from the key type and the rest will be cleared. ++ ++ If a description can be proposed from the payload contents, that should be ++ attached as a string to the description field. This will be used for the ++ key description if the caller of add_key() passes NULL or "". ++ ++ The method can attach anything it likes to type_data[] and payload. These ++ are merely passed along to the instantiate() or update() operations. ++ ++ The method should return 0 if success ful or a negative error code ++ otherwise. ++ ++ ++ (*) void (*free_preparse)(struct key_preparsed_payload *prep); ++ ++ This method is only required if the preparse() method is provided, ++ otherwise it is unused. It cleans up anything attached to the ++ description, type_data and payload fields of the key_preparsed_payload ++ struct as filled in by the preparse() method. ++ ++ ++ (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); + + This method is called to attach a payload to a key during construction. + The payload attached need not bear any relation to the data passed to this + function. + ++ The prep->data and prep->datalen fields will define the original payload ++ blob. If preparse() was supplied then other fields may be filled in also. ++ + If the amount of data attached to the key differs from the size in + keytype->def_datalen, then key_payload_reserve() should be called. + +@@ -1135,6 +1180,9 @@ The structure has a number of fields, some of which are mandatory: + If this type of key can be updated, then this method should be provided. + It is called to update a key's payload from the blob of data provided. + ++ The prep->data and prep->datalen fields will define the original payload ++ blob. If preparse() was supplied then other fields may be filled in also. ++ + key_payload_reserve() should be called if the data length might change + before any changes are actually made. Note that if this succeeds, the type + 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 e622863..086f381 100644 +--- a/fs/cifs/cifs_spnego.c ++++ b/fs/cifs/cifs_spnego.c +@@ -31,18 +31,18 @@ + + /* create a new cifs key */ + static int +-cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) ++cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + { + char *payload; + int ret; + + ret = -ENOMEM; +- payload = kmalloc(datalen, GFP_KERNEL); ++ payload = kmalloc(prep->datalen, GFP_KERNEL); + if (!payload) + goto error; + + /* attach the data */ +- memcpy(payload, data, datalen); ++ memcpy(payload, prep->data, prep->datalen); + key->payload.data = payload; + ret = 0; + +diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c +index 05f4dc2..f3c60e2 100644 +--- a/fs/cifs/cifsacl.c ++++ b/fs/cifs/cifsacl.c +@@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = { + }; + + static int +-cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen) ++cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + { + char *payload; + +- payload = kmalloc(datalen, GFP_KERNEL); ++ payload = kmalloc(prep->datalen, GFP_KERNEL); + if (!payload) + return -ENOMEM; + +- memcpy(payload, data, datalen); ++ memcpy(payload, prep->data, prep->datalen); + key->payload.data = payload; +- key->datalen = datalen; ++ key->datalen = prep->datalen; + return 0; + } + +diff --git a/include/keys/user-type.h b/include/keys/user-type.h +index bc9ec1d..5e452c8 100644 +--- a/include/keys/user-type.h ++++ b/include/keys/user-type.h +@@ -35,8 +35,10 @@ struct user_key_payload { + extern struct key_type key_type_user; + extern struct key_type key_type_logon; + +-extern int user_instantiate(struct key *key, const void *data, size_t datalen); +-extern int user_update(struct key *key, const void *data, size_t datalen); ++struct key_preparsed_payload; ++ ++extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); ++extern int user_update(struct key *key, struct key_preparsed_payload *prep); + extern int user_match(const struct key *key, const void *criterion); + extern void user_revoke(struct key *key); + extern void user_destroy(struct key *key); +diff --git a/include/linux/key-type.h b/include/linux/key-type.h +index f0c651c..518a53a 100644 +--- a/include/linux/key-type.h ++++ b/include/linux/key-type.h +@@ -26,6 +26,27 @@ struct key_construction { + struct key *authkey;/* authorisation for key being constructed */ + }; + ++/* ++ * Pre-parsed payload, used by key add, update and instantiate. ++ * ++ * This struct will be cleared and data and datalen will be set with the data ++ * and length parameters from the caller and quotalen will be set from ++ * def_datalen from the key type. Then if the preparse() op is provided by the ++ * key type, that will be called. Then the struct will be passed to the ++ * instantiate() or the update() op. ++ * ++ * If the preparse() op is given, the free_preparse() op will be called to ++ * clear the contents. ++ */ ++struct key_preparsed_payload { ++ char *description; /* Proposed key description (or NULL) */ ++ void *type_data[2]; /* Private key-type data */ ++ void *payload; /* Proposed payload */ ++ const void *data; /* Raw data */ ++ size_t datalen; /* Raw datalen */ ++ size_t quotalen; /* Quota length for proposed payload */ ++}; ++ + typedef int (*request_key_actor_t)(struct key_construction *key, + const char *op, void *aux); + +@@ -45,18 +66,28 @@ struct key_type { + /* vet a description */ + int (*vet_description)(const char *description); + ++ /* Preparse the data blob from userspace that is to be the payload, ++ * generating a proposed description and payload that will be handed to ++ * the instantiate() and update() ops. ++ */ ++ int (*preparse)(struct key_preparsed_payload *prep); ++ ++ /* Free a preparse data structure. ++ */ ++ void (*free_preparse)(struct key_preparsed_payload *prep); ++ + /* instantiate a key of this type + * - this method should call key_payload_reserve() to determine if the + * user's quota will hold the payload + */ +- int (*instantiate)(struct key *key, const void *data, size_t datalen); ++ int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); + + /* update a key of this type (optional) + * - this method should call key_payload_reserve() to recalculate the + * quota consumption + * - the key must be locked against read when modifying + */ +- int (*update)(struct key *key, const void *data, size_t datalen); ++ int (*update)(struct key *key, struct key_preparsed_payload *prep); + + /* match a key against a description */ + int (*match)(const struct key *key, const void *desc); +diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c +index 9da7fdd..af14cb4 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, + } + } + +-int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) ++int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep) + { + struct ceph_crypto_key *ckey; ++ size_t datalen = prep->datalen; + int ret; + void *p; + + ret = -EINVAL; +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + goto err; + + ret = key_payload_reserve(key, datalen); +@@ -443,8 +444,8 @@ int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) + goto err; + + /* TODO ceph_crypto_key_decode should really take const input */ +- p = (void *)data; +- ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); ++ p = (void *)prep->data; ++ ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen); + if (ret < 0) + goto err_ckey; + +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index d9507dd..859ab8b 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; + * "ip1,ip2,...#foo=bar" + */ + static int +-dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen) ++dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) + { + struct user_key_payload *upayload; + unsigned long derrno; + int ret; +- size_t result_len = 0; +- const char *data = _data, *end, *opt; ++ size_t datalen = prep->datalen, result_len = 0; ++ const char *data = prep->data, *end, *opt; + + kenter("%%%d,%s,'%*.*s',%zu", + key->serial, key->description, +diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c +index 8b1f9f4..106c5a6 100644 +--- a/net/rxrpc/ar-key.c ++++ b/net/rxrpc/ar-key.c +@@ -26,8 +26,8 @@ + #include "ar-internal.h" + + static int rxrpc_vet_description_s(const char *); +-static int rxrpc_instantiate(struct key *, const void *, size_t); +-static int rxrpc_instantiate_s(struct key *, const void *, size_t); ++static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *); ++static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); + static void rxrpc_destroy(struct key *); + static void rxrpc_destroy_s(struct key *); + static void rxrpc_describe(const struct key *, struct seq_file *); +@@ -678,7 +678,7 @@ error: + * + * if no data is provided, then a no-security key is made + */ +-static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) ++static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) + { + const struct rxrpc_key_data_v1 *v1; + struct rxrpc_key_token *token, **pp; +@@ -686,26 +686,26 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) + u32 kver; + int ret; + +- _enter("{%x},,%zu", key_serial(key), datalen); ++ _enter("{%x},,%zu", key_serial(key), prep->datalen); + + /* handle a no-security key */ +- if (!data && datalen == 0) ++ if (!prep->data && prep->datalen == 0) + return 0; + + /* determine if the XDR payload format is being used */ +- if (datalen > 7 * 4) { +- ret = rxrpc_instantiate_xdr(key, data, datalen); ++ if (prep->datalen > 7 * 4) { ++ ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); + if (ret != -EPROTO) + return ret; + } + + /* get the key interface version number */ + ret = -EINVAL; +- if (datalen <= 4 || !data) ++ if (prep->datalen <= 4 || !prep->data) + goto error; +- memcpy(&kver, data, sizeof(kver)); +- data += sizeof(kver); +- datalen -= sizeof(kver); ++ memcpy(&kver, prep->data, sizeof(kver)); ++ prep->data += sizeof(kver); ++ prep->datalen -= sizeof(kver); + + _debug("KEY I/F VERSION: %u", kver); + +@@ -715,11 +715,11 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) + + /* deal with a version 1 key */ + ret = -EINVAL; +- if (datalen < sizeof(*v1)) ++ if (prep->datalen < sizeof(*v1)) + goto error; + +- v1 = data; +- if (datalen != sizeof(*v1) + v1->ticket_length) ++ v1 = prep->data; ++ if (prep->datalen != sizeof(*v1) + v1->ticket_length) + goto error; + + _debug("SCIX: %u", v1->security_index); +@@ -784,17 +784,17 @@ error: + * instantiate a server secret key + * data should be a pointer to the 8-byte secret key + */ +-static int rxrpc_instantiate_s(struct key *key, const void *data, +- size_t datalen) ++static int rxrpc_instantiate_s(struct key *key, ++ struct key_preparsed_payload *prep) + { + struct crypto_blkcipher *ci; + +- _enter("{%x},,%zu", key_serial(key), datalen); ++ _enter("{%x},,%zu", key_serial(key), prep->datalen); + +- if (datalen != 8) ++ if (prep->datalen != 8) + return -EINVAL; + +- memcpy(&key->type_data, data, 8); ++ memcpy(&key->type_data, prep->data, 8); + + ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(ci)) { +@@ -802,7 +802,7 @@ static int rxrpc_instantiate_s(struct key *key, const void *data, + return PTR_ERR(ci); + } + +- if (crypto_blkcipher_setkey(ci, data, 8) < 0) ++ if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) + BUG(); + + key->payload.data = ci; +diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c +index 2d1bb8a..9e1e005 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, + * + * On success, return 0. Otherwise return errno. + */ +-static int encrypted_instantiate(struct key *key, const void *data, +- size_t datalen) ++static int encrypted_instantiate(struct key *key, ++ struct key_preparsed_payload *prep) + { + struct encrypted_key_payload *epayload = NULL; + char *datablob = NULL; +@@ -782,16 +782,17 @@ static int encrypted_instantiate(struct key *key, const void *data, + char *master_desc = NULL; + char *decrypted_datalen = NULL; + char *hex_encoded_iv = NULL; ++ size_t datalen = prep->datalen; + int ret; + +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + return -EINVAL; + + datablob = kmalloc(datalen + 1, GFP_KERNEL); + if (!datablob) + return -ENOMEM; + datablob[datalen] = 0; +- memcpy(datablob, data, datalen); ++ memcpy(datablob, prep->data, datalen); + ret = datablob_parse(datablob, &format, &master_desc, + &decrypted_datalen, &hex_encoded_iv); + if (ret < 0) +@@ -834,16 +835,17 @@ static void encrypted_rcu_free(struct rcu_head *rcu) + * + * On success, return 0. Otherwise return errno. + */ +-static int encrypted_update(struct key *key, const void *data, size_t datalen) ++static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) + { + struct encrypted_key_payload *epayload = key->payload.data; + struct encrypted_key_payload *new_epayload; + char *buf; + char *new_master_desc = NULL; + const char *format = NULL; ++ size_t datalen = prep->datalen; + int ret = 0; + +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + return -EINVAL; + + buf = kmalloc(datalen + 1, GFP_KERNEL); +@@ -851,7 +853,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) + return -ENOMEM; + + buf[datalen] = 0; +- memcpy(buf, data, datalen); ++ memcpy(buf, prep->data, datalen); + ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); + if (ret < 0) + goto out; +diff --git a/security/keys/key.c b/security/keys/key.c +index 50d96d4..732a53e 100644 +--- a/security/keys/key.c ++++ b/security/keys/key.c +@@ -412,8 +412,7 @@ EXPORT_SYMBOL(key_payload_reserve); + * key_construction_mutex. + */ + static int __key_instantiate_and_link(struct key *key, +- const void *data, +- size_t datalen, ++ struct key_preparsed_payload *prep, + struct key *keyring, + struct key *authkey, + unsigned long *_prealloc) +@@ -431,7 +430,7 @@ static int __key_instantiate_and_link(struct key *key, + /* can't instantiate twice */ + if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { + /* instantiate the key */ +- ret = key->type->instantiate(key, data, datalen); ++ ret = key->type->instantiate(key, prep); + + if (ret == 0) { + /* mark the key as being instantiated */ +@@ -482,22 +481,37 @@ int key_instantiate_and_link(struct key *key, + struct key *keyring, + struct key *authkey) + { ++ struct key_preparsed_payload prep; + unsigned long prealloc; + int ret; + ++ memset(&prep, 0, sizeof(prep)); ++ prep.data = data; ++ prep.datalen = datalen; ++ prep.quotalen = key->type->def_datalen; ++ if (key->type->preparse) { ++ ret = key->type->preparse(&prep); ++ if (ret < 0) ++ goto error; ++ } ++ + if (keyring) { + ret = __key_link_begin(keyring, key->type, key->description, + &prealloc); + if (ret < 0) +- return ret; ++ goto error_free_preparse; + } + +- ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey, ++ ret = __key_instantiate_and_link(key, &prep, keyring, authkey, + &prealloc); + + if (keyring) + __key_link_end(keyring, key->type, prealloc); + ++error_free_preparse: ++ if (key->type->preparse) ++ key->type->free_preparse(&prep); ++error: + return ret; + } + +@@ -706,7 +720,7 @@ void key_type_put(struct key_type *ktype) + * if we get an error. + */ + static inline key_ref_t __key_update(key_ref_t key_ref, +- const void *payload, size_t plen) ++ struct key_preparsed_payload *prep) + { + struct key *key = key_ref_to_ptr(key_ref); + int ret; +@@ -722,7 +736,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref, + + down_write(&key->sem); + +- ret = key->type->update(key, payload, plen); ++ ret = key->type->update(key, prep); + if (ret == 0) + /* updating a negative key instantiates it */ + clear_bit(KEY_FLAG_NEGATIVE, &key->flags); +@@ -774,6 +788,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, + unsigned long flags) + { + unsigned long prealloc; ++ struct key_preparsed_payload prep; + const struct cred *cred = current_cred(); + struct key_type *ktype; + struct key *keyring, *key = NULL; +@@ -789,8 +804,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, + } + + key_ref = ERR_PTR(-EINVAL); +- if (!ktype->match || !ktype->instantiate) +- goto error_2; ++ if (!ktype->match || !ktype->instantiate || ++ (!description && !ktype->preparse)) ++ goto error_put_type; + + keyring = key_ref_to_ptr(keyring_ref); + +@@ -798,18 +814,33 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, + + key_ref = ERR_PTR(-ENOTDIR); + if (keyring->type != &key_type_keyring) +- goto error_2; ++ goto error_put_type; ++ ++ memset(&prep, 0, sizeof(prep)); ++ prep.data = payload; ++ prep.datalen = plen; ++ prep.quotalen = ktype->def_datalen; ++ if (ktype->preparse) { ++ ret = ktype->preparse(&prep); ++ if (ret < 0) ++ goto error_put_type; ++ if (!description) ++ description = prep.description; ++ ret = -EINVAL; ++ if (!description) ++ goto error_free_prep; ++ } + + ret = __key_link_begin(keyring, ktype, description, &prealloc); + if (ret < 0) +- goto error_2; ++ goto error_free_prep; + + /* if we're going to allocate a new key, we're going to have + * to modify the keyring */ + ret = key_permission(keyring_ref, KEY_WRITE); + if (ret < 0) { + key_ref = ERR_PTR(ret); +- goto error_3; ++ goto error_link_end; + } + + /* if it's possible to update this type of key, search for an existing +@@ -840,25 +871,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, + perm, flags); + if (IS_ERR(key)) { + key_ref = ERR_CAST(key); +- goto error_3; ++ goto error_link_end; + } + + /* instantiate it and link it into the target keyring */ +- ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL, +- &prealloc); ++ ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc); + if (ret < 0) { + key_put(key); + key_ref = ERR_PTR(ret); +- goto error_3; ++ goto error_link_end; + } + + key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); + +- error_3: ++error_link_end: + __key_link_end(keyring, ktype, prealloc); +- error_2: ++error_free_prep: ++ if (ktype->preparse) ++ ktype->free_preparse(&prep); ++error_put_type: + key_type_put(ktype); +- error: ++error: + return key_ref; + + found_matching_key: +@@ -866,10 +899,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, + * - we can drop the locks first as we have the key pinned + */ + __key_link_end(keyring, ktype, prealloc); +- key_type_put(ktype); + +- key_ref = __key_update(key_ref, payload, plen); +- goto error; ++ key_ref = __key_update(key_ref, &prep); ++ goto error_free_prep; + } + EXPORT_SYMBOL(key_create_or_update); + +@@ -888,6 +920,7 @@ EXPORT_SYMBOL(key_create_or_update); + */ + int key_update(key_ref_t key_ref, const void *payload, size_t plen) + { ++ struct key_preparsed_payload prep; + struct key *key = key_ref_to_ptr(key_ref); + int ret; + +@@ -900,18 +933,31 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) + + /* attempt to update it if supported */ + ret = -EOPNOTSUPP; +- if (key->type->update) { +- down_write(&key->sem); +- +- ret = key->type->update(key, payload, plen); +- if (ret == 0) +- /* updating a negative key instantiates it */ +- clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ if (!key->type->update) ++ goto error; + +- up_write(&key->sem); ++ memset(&prep, 0, sizeof(prep)); ++ prep.data = payload; ++ prep.datalen = plen; ++ prep.quotalen = key->type->def_datalen; ++ if (key->type->preparse) { ++ ret = key->type->preparse(&prep); ++ if (ret < 0) ++ goto error; + } + +- error: ++ down_write(&key->sem); ++ ++ ret = key->type->update(key, &prep); ++ if (ret == 0) ++ /* updating a negative key instantiates it */ ++ clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ ++ up_write(&key->sem); ++ ++ if (key->type->preparse) ++ key->type->free_preparse(&prep); ++error: + return ret; + } + EXPORT_SYMBOL(key_update); +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index 3364fbf..505d40b 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -46,6 +46,9 @@ static int key_get_type_from_user(char *type, + * Extract the description of a new key from userspace and either add it as a + * new key to the specified keyring or update a matching key in that keyring. + * ++ * If the description is NULL or an empty string, the key type is asked to ++ * generate one from the payload. ++ * + * The keyring must be writable so that we can attach the key to it. + * + * 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, + if (ret < 0) + goto error; + +- description = strndup_user(_description, PAGE_SIZE); +- if (IS_ERR(description)) { +- ret = PTR_ERR(description); +- goto error; ++ description = NULL; ++ if (_description) { ++ description = strndup_user(_description, PAGE_SIZE); ++ if (IS_ERR(description)) { ++ ret = PTR_ERR(description); ++ goto error; ++ } ++ if (!*description) { ++ kfree(description); ++ description = NULL; ++ } + } + + /* pull the payload in if one was supplied */ +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +index 81e7852..f04d8cf 100644 +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -66,7 +66,7 @@ static inline unsigned keyring_hash(const char *desc) + * operations. + */ + static int keyring_instantiate(struct key *keyring, +- const void *data, size_t datalen); ++ struct key_preparsed_payload *prep); + static int keyring_match(const struct key *keyring, const void *criterion); + static void keyring_revoke(struct key *keyring); + static void keyring_destroy(struct key *keyring); +@@ -121,12 +121,12 @@ static void keyring_publish_name(struct key *keyring) + * Returns 0 on success, -EINVAL if given any data. + */ + static int keyring_instantiate(struct key *keyring, +- const void *data, size_t datalen) ++ struct key_preparsed_payload *prep) + { + int ret; + + ret = -EINVAL; +- if (datalen == 0) { ++ if (prep->datalen == 0) { + /* make the keyring available by name if it has one */ + keyring_publish_name(keyring); + ret = 0; +diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c +index 60d4e3f..85730d5 100644 +--- a/security/keys/request_key_auth.c ++++ b/security/keys/request_key_auth.c +@@ -19,7 +19,8 @@ + #include + #include "internal.h" + +-static int request_key_auth_instantiate(struct key *, const void *, size_t); ++static int request_key_auth_instantiate(struct key *, ++ struct key_preparsed_payload *); + static void request_key_auth_describe(const struct key *, struct seq_file *); + static void request_key_auth_revoke(struct key *); + static void request_key_auth_destroy(struct key *); +@@ -42,10 +43,9 @@ struct key_type key_type_request_key_auth = { + * Instantiate a request-key authorisation key. + */ + static int request_key_auth_instantiate(struct key *key, +- const void *data, +- size_t datalen) ++ struct key_preparsed_payload *prep) + { +- key->payload.data = (struct request_key_auth *) data; ++ key->payload.data = (struct request_key_auth *)prep->data; + return 0; + } + +diff --git a/security/keys/trusted.c b/security/keys/trusted.c +index 2d5d041..42036c7 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) + * + * On success, return 0. Otherwise return errno. + */ +-static int trusted_instantiate(struct key *key, const void *data, +- size_t datalen) ++static int trusted_instantiate(struct key *key, ++ struct key_preparsed_payload *prep) + { + struct trusted_key_payload *payload = NULL; + struct trusted_key_options *options = NULL; ++ size_t datalen = prep->datalen; + char *datablob; + int ret = 0; + int key_cmd; + +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + return -EINVAL; + + datablob = kmalloc(datalen + 1, GFP_KERNEL); + if (!datablob) + return -ENOMEM; +- memcpy(datablob, data, datalen); ++ memcpy(datablob, prep->data, datalen); + datablob[datalen] = '\0'; + + options = trusted_options_alloc(); +@@ -1011,17 +1012,18 @@ static void trusted_rcu_free(struct rcu_head *rcu) + /* + * trusted_update - reseal an existing key with new PCR values + */ +-static int trusted_update(struct key *key, const void *data, size_t datalen) ++static int trusted_update(struct key *key, struct key_preparsed_payload *prep) + { + struct trusted_key_payload *p = key->payload.data; + struct trusted_key_payload *new_p; + struct trusted_key_options *new_o; ++ size_t datalen = prep->datalen; + char *datablob; + int ret = 0; + + if (!p->migratable) + return -EPERM; +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + return -EINVAL; + + datablob = kmalloc(datalen + 1, GFP_KERNEL); +@@ -1038,7 +1040,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen) + goto out; + } + +- memcpy(datablob, data, datalen); ++ memcpy(datablob, prep->data, datalen); + datablob[datalen] = '\0'; + ret = datablob_parse(datablob, new_p, new_o); + if (ret != Opt_update) { +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index c7660a2..55dc889 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -58,13 +58,14 @@ EXPORT_SYMBOL_GPL(key_type_logon); + /* + * instantiate a user defined key + */ +-int user_instantiate(struct key *key, const void *data, size_t datalen) ++int user_instantiate(struct key *key, struct key_preparsed_payload *prep) + { + struct user_key_payload *upayload; ++ size_t datalen = prep->datalen; + int ret; + + ret = -EINVAL; +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + goto error; + + ret = key_payload_reserve(key, datalen); +@@ -78,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen) + + /* attach the data */ + upayload->datalen = datalen; +- memcpy(upayload->data, data, datalen); ++ memcpy(upayload->data, prep->data, datalen); + rcu_assign_keypointer(key, upayload); + ret = 0; + +@@ -92,13 +93,14 @@ EXPORT_SYMBOL_GPL(user_instantiate); + * update a user defined key + * - the key's semaphore is write-locked + */ +-int user_update(struct key *key, const void *data, size_t datalen) ++int user_update(struct key *key, struct key_preparsed_payload *prep) + { + struct user_key_payload *upayload, *zap; ++ size_t datalen = prep->datalen; + int ret; + + ret = -EINVAL; +- if (datalen <= 0 || datalen > 32767 || !data) ++ if (datalen <= 0 || datalen > 32767 || !prep->data) + goto error; + + /* construct a replacement payload */ +@@ -108,7 +110,7 @@ int user_update(struct key *key, const void *data, size_t datalen) + goto error; + + upayload->datalen = datalen; +- memcpy(upayload->data, data, datalen); ++ memcpy(upayload->data, prep->data, datalen); + + /* check the quota and attach the new data */ + zap = upayload; +-- +1.7.11.4 + + +From 2f5f2d483565648dbe050fda8767edd5d65b1d98 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Thu, 16 Aug 2012 00:14:17 +0100 +Subject: [PATCH 02/32] MPILIB: Provide count_leading/trailing_zeros() based on arch functions Provide count_leading/trailing_zeros() macros based on extant arch bit scanning @@ -356,13 +1312,13 @@ index 67f3e79..5464c87 100644 c = BITS_PER_MPI_LIMB - 1 - c; -- -1.7.11.2 +1.7.11.4 -From 1d6e2f2b87e6651bead1c0ccca699681f92dd52c Mon Sep 17 00:00:00 2001 +From 15b76403afcc626b91e5fcee8b6a950a51f284ef Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 13:59:51 +0100 -Subject: [PATCH 02/28] KEYS: Create a key type that can be used for general +Date: Thu, 16 Aug 2012 00:14:18 +0100 +Subject: [PATCH 03/32] KEYS: Create a key type that can be used for general cryptographic operations Create a key type that can be used for general cryptographic operations, such @@ -373,16 +1329,16 @@ algorithms. Signed-off-by: David Howells --- - Documentation/security/keys-crypto.txt | 181 ++++++++++++++++++++++++++ - include/keys/crypto-subtype.h | 56 ++++++++ - include/keys/crypto-type.h | 25 ++++ + Documentation/security/keys-crypto.txt | 181 ++++++++++++++++++++++ + include/keys/crypto-subtype.h | 57 +++++++ + include/keys/crypto-type.h | 25 +++ security/keys/Kconfig | 2 + security/keys/Makefile | 1 + security/keys/crypto/Kconfig | 7 + security/keys/crypto/Makefile | 7 + security/keys/crypto/crypto_keys.h | 28 ++++ - security/keys/crypto/crypto_type.c | 228 +++++++++++++++++++++++++++++++++ - 9 files changed, 535 insertions(+) + security/keys/crypto/crypto_type.c | 272 +++++++++++++++++++++++++++++++++ + 9 files changed, 580 insertions(+) create mode 100644 Documentation/security/keys-crypto.txt create mode 100644 include/keys/crypto-subtype.h create mode 100644 include/keys/crypto-type.h @@ -580,10 +1536,10 @@ index 0000000..97dee80 + reference on the subtype module. diff --git a/include/keys/crypto-subtype.h b/include/keys/crypto-subtype.h new file mode 100644 -index 0000000..fa87555 +index 0000000..1f546e6 --- /dev/null +++ b/include/keys/crypto-subtype.h -@@ -0,0 +1,56 @@ +@@ -0,0 +1,57 @@ +/* Cryptographic key subtype + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -628,12 +1584,13 @@ index 0000000..fa87555 + struct module *owner; + const char *name; + -+ /* Attempt to instantiate a key from the data blob passed to add_key() -+ * or keyctl_instantiate(). ++ /* Attempt to parse a key from the data blob passed to add_key() or ++ * keyctl_instantiate(). Should also generate a proposed description ++ * that the caller can optionally use for the key. + * + * Return EBADMSG if not recognised. + */ -+ int (*instantiate)(struct key *key, const void *data, size_t datalen); ++ int (*preparse)(struct key_preparsed_payload *prep); +}; + +extern int register_crypto_key_parser(struct crypto_key_parser *); @@ -718,7 +1675,7 @@ index 0000000..36db1d5 +crypto_keys-y := crypto_type.o diff --git a/security/keys/crypto/crypto_keys.h b/security/keys/crypto/crypto_keys.h new file mode 100644 -index 0000000..a339ce0 +index 0000000..eb11788 --- /dev/null +++ b/security/keys/crypto/crypto_keys.h @@ -0,0 +1,28 @@ @@ -739,7 +1696,7 @@ index 0000000..a339ce0 + return key->type_data.p[0]; +} + -+static inline char *crypto_key_id(const struct key *key) ++static inline const char *crypto_key_id(const struct key *key) +{ + return key->type_data.p[1]; +} @@ -752,10 +1709,10 @@ index 0000000..a339ce0 +extern struct rw_semaphore crypto_key_parsers_sem; diff --git a/security/keys/crypto/crypto_type.c b/security/keys/crypto/crypto_type.c new file mode 100644 -index 0000000..33d279b +index 0000000..e8f83a6 --- /dev/null +++ b/security/keys/crypto/crypto_type.c -@@ -0,0 +1,228 @@ +@@ -0,0 +1,272 @@ +/* Cryptographic key type + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -868,17 +1825,20 @@ index 0000000..33d279b +} + +/* -+ * Instantiate a crypto_key defined key ++ * Preparse a crypto payload to get format the contents appropriately for the ++ * internal payload to cut down on the number of scans of the data performed. ++ * ++ * We also generate a proposed description from the contents of the key that ++ * can be used to name the key if the user doesn't want to provide one. + */ -+static int crypto_key_instantiate(struct key *key, -+ const void *data, size_t datalen) ++static int crypto_key_preparse(struct key_preparsed_payload *prep) +{ + struct crypto_key_parser *parser; + int ret; + + pr_devel("==>%s()\n", __func__); + -+ if (datalen == 0) ++ if (prep->datalen == 0) + return -EINVAL; + + down_read(&crypto_key_parsers_sem); @@ -887,7 +1847,7 @@ index 0000000..33d279b + list_for_each_entry(parser, &crypto_key_parsers, link) { + pr_debug("Trying parser '%s'\n", parser->name); + -+ ret = parser->instantiate(key, data, datalen); ++ ret = parser->preparse(prep); + if (ret != -EBADMSG) { + pr_debug("Parser recognised the format (ret %d)\n", + ret); @@ -901,6 +1861,45 @@ index 0000000..33d279b +} + +/* ++ * Clean up the preparse data ++ */ ++static void crypto_key_free_preparse(struct key_preparsed_payload *prep) ++{ ++ struct crypto_key_subtype *subtype = prep->type_data[0]; ++ ++ pr_devel("==>%s()\n", __func__); ++ ++ if (subtype) { ++ subtype->destroy(prep->payload); ++ module_put(subtype->owner); ++ } ++ kfree(prep->type_data[1]); ++ kfree(prep->description); ++} ++ ++/* ++ * Instantiate a crypto_key defined key ++ */ ++static int crypto_key_instantiate(struct key *key, struct key_preparsed_payload *prep) ++{ ++ int ret; ++ ++ pr_devel("==>%s()\n", __func__); ++ ++ ret = key_payload_reserve(key, prep->quotalen); ++ if (ret == 0) { ++ key->type_data.p[0] = prep->type_data[0]; ++ key->type_data.p[1] = prep->type_data[1]; ++ key->payload.data = prep->payload; ++ prep->type_data[0] = NULL; ++ prep->type_data[1] = NULL; ++ prep->payload = NULL; ++ } ++ pr_devel("<==%s() = %d\n", __func__, ret); ++ return ret; ++} ++ ++/* + * dispose of the data dangling from the corpse of a crypto key + */ +static void crypto_key_destroy(struct key *key) @@ -917,6 +1916,8 @@ index 0000000..33d279b + +struct key_type key_type_crypto = { + .name = "crypto", ++ .preparse = crypto_key_preparse, ++ .free_preparse = crypto_key_free_preparse, + .instantiate = crypto_key_instantiate, + .match = crypto_key_match, + .destroy = crypto_key_destroy, @@ -985,13 +1986,13 @@ index 0000000..33d279b +module_init(crypto_key_init); +module_exit(crypto_key_cleanup); -- -1.7.11.2 +1.7.11.4 -From 24d9655ce0fc046012078867baaedd3bf2eaedd2 Mon Sep 17 00:00:00 2001 +From a4e8ef15db9c013c4d3141424120c5ba74376483 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 13:59:51 +0100 -Subject: [PATCH 03/28] KEYS: Add signature verification facility +Date: Thu, 16 Aug 2012 00:14:18 +0100 +Subject: [PATCH 04/32] KEYS: Add signature verification facility Add a facility whereby a key subtype may be asked to verify a signature against the data it is purported to have signed. @@ -1023,16 +2024,18 @@ This adds four routines: Signed-off-by: David Howells --- - Documentation/security/keys-crypto.txt | 101 +++++++++++++++++++++++++++++ - include/keys/crypto-subtype.h | 21 +++++++ - include/keys/crypto-type.h | 9 +++ + Documentation/security/keys-crypto.txt | 100 +++++++++++++++++++++ + include/keys/crypto-subtype.h | 36 +++++++- + include/keys/crypto-type.h | 9 ++ security/keys/crypto/Makefile | 2 +- - security/keys/crypto/crypto_verify.c | 112 +++++++++++++++++++++++++++++++++ - 5 files changed, 244 insertions(+), 1 deletion(-) + security/keys/crypto/crypto_keys.h | 1 - + security/keys/crypto/crypto_type.c | 2 +- + security/keys/crypto/crypto_verify.c | 159 +++++++++++++++++++++++++++++++++ + 7 files changed, 304 insertions(+), 5 deletions(-) create mode 100644 security/keys/crypto/crypto_verify.c diff --git a/Documentation/security/keys-crypto.txt b/Documentation/security/keys-crypto.txt -index 97dee80..a964717 100644 +index 97dee80..0a886ec 100644 --- a/Documentation/security/keys-crypto.txt +++ b/Documentation/security/keys-crypto.txt @@ -7,6 +7,7 @@ Contents: @@ -1109,15 +2112,7 @@ index 97dee80..a964717 100644 =========================== IMPLEMENTING CRYPTO PARSERS =========================== -@@ -96,6 +156,7 @@ IMPLEMENTING CRYPTO PARSERS - The crypto key type keeps a list of registered data parsers. An example of - such a parser is one that parses OpenPGP packet formatted data [RFC 4880]. - -+ - During key instantiation each parser in the list is tried until one doesn't - return -EBADMSG. - -@@ -107,6 +168,8 @@ The parser definition structure looks like the following: +@@ -107,6 +167,8 @@ The parser definition structure looks like the following: int (*instantiate)(struct key *key, const void *data, size_t datalen); @@ -1126,7 +2121,7 @@ index 97dee80..a964717 100644 }; The owner and name fields should be set to the owning module and the name of -@@ -135,6 +198,44 @@ but it is expected that at least one will be defined. +@@ -135,6 +197,44 @@ but it is expected that at least one will be defined. algorithm such as RSA and DSA this will likely be a printable hex version of the key's fingerprint. @@ -1172,60 +2167,73 @@ index 97dee80..a964717 100644 int register_crypto_key_parser(struct crypto_key_parser *parser); diff --git a/include/keys/crypto-subtype.h b/include/keys/crypto-subtype.h -index fa87555..f2b927a 100644 +index 1f546e6..61a5338 100644 --- a/include/keys/crypto-subtype.h +++ b/include/keys/crypto-subtype.h -@@ -20,6 +20,20 @@ - extern struct key_type key_type_crypto; +@@ -34,8 +34,7 @@ struct crypto_key_subtype { + }; /* +- * Data parser. Called during instantiation and signature verification +- * initiation. ++ * Key data parser. Called during key instantiation. + */ + struct crypto_key_parser { + struct list_head link; +@@ -54,4 +53,37 @@ struct crypto_key_parser { + extern int register_crypto_key_parser(struct crypto_key_parser *); + extern void unregister_crypto_key_parser(struct crypto_key_parser *); + ++/* + * Context base for signature verification methods. Allocated by the subtype + * and presumably embedded in something appropriate. + */ -+struct crypto_key_verify_context { ++struct crypto_sig_verify_context { + struct key *key; -+ struct crypto_key_parser *parser; -+ int (*add_data)(struct crypto_key_verify_context *ctx, ++ struct crypto_sig_parser *parser; ++ int (*add_data)(struct crypto_sig_verify_context *ctx, + const void *data, size_t datalen); -+ int (*end)(struct crypto_key_verify_context *ctx, ++ int (*end)(struct crypto_sig_verify_context *ctx, + const u8 *sig, size_t siglen); -+ void (*cancel)(struct crypto_key_verify_context *ctx); ++ void (*cancel)(struct crypto_sig_verify_context *ctx); +}; + +/* - * Keys of this type declare a subtype that indicates the handlers and - * capabilities. - */ -@@ -48,6 +62,13 @@ struct crypto_key_parser { - * Return EBADMSG if not recognised. - */ - int (*instantiate)(struct key *key, const void *data, size_t datalen); ++ * Signature data parser. Called during signature verification initiation. ++ */ ++struct crypto_sig_parser { ++ struct list_head link; ++ struct module *owner; ++ const char *name; + + /* Attempt to recognise a signature blob and find a matching key. + * + * Return EBADMSG if not recognised. + */ -+ struct crypto_key_verify_context *(*verify_sig_begin)( ++ struct crypto_sig_verify_context *(*verify_sig_begin)( + struct key *keyring, const u8 *sig, size_t siglen); - }; - - extern int register_crypto_key_parser(struct crypto_key_parser *); ++}; ++ ++extern int register_crypto_sig_parser(struct crypto_sig_parser *); ++extern void unregister_crypto_sig_parser(struct crypto_sig_parser *); ++ + #endif /* _KEYS_CRYPTO_SUBTYPE_H */ diff --git a/include/keys/crypto-type.h b/include/keys/crypto-type.h -index 47c00c7..6b93366 100644 +index 47c00c7..0fb362a 100644 --- a/include/keys/crypto-type.h +++ b/include/keys/crypto-type.h @@ -18,6 +18,15 @@ extern struct key_type key_type_crypto; -+struct crypto_key_verify_context; -+extern struct crypto_key_verify_context *verify_sig_begin( ++struct crypto_sig_verify_context; ++extern struct crypto_sig_verify_context *verify_sig_begin( + struct key *key, const void *sig, size_t siglen); -+extern int verify_sig_add_data(struct crypto_key_verify_context *ctx, ++extern int verify_sig_add_data(struct crypto_sig_verify_context *ctx, + const void *data, size_t datalen); -+extern int verify_sig_end(struct crypto_key_verify_context *ctx, ++extern int verify_sig_end(struct crypto_sig_verify_context *ctx, + const void *sig, size_t siglen); -+extern void verify_sig_cancel(struct crypto_key_verify_context *ctx); ++extern void verify_sig_cancel(struct crypto_sig_verify_context *ctx); + /* * The payload is at the discretion of the subtype. @@ -1240,12 +2248,35 @@ index 36db1d5..67001bc 100644 -crypto_keys-y := crypto_type.o +crypto_keys-y := crypto_type.o crypto_verify.o +diff --git a/security/keys/crypto/crypto_keys.h b/security/keys/crypto/crypto_keys.h +index eb11788..ab9b381 100644 +--- a/security/keys/crypto/crypto_keys.h ++++ b/security/keys/crypto/crypto_keys.h +@@ -24,5 +24,4 @@ static inline const char *crypto_key_id(const struct key *key) + /* + * crypto_type.c + */ +-extern struct list_head crypto_key_parsers; + extern struct rw_semaphore crypto_key_parsers_sem; +diff --git a/security/keys/crypto/crypto_type.c b/security/keys/crypto/crypto_type.c +index e8f83a6..821db37 100644 +--- a/security/keys/crypto/crypto_type.c ++++ b/security/keys/crypto/crypto_type.c +@@ -18,7 +18,7 @@ + + MODULE_LICENSE("GPL"); + +-LIST_HEAD(crypto_key_parsers); ++static LIST_HEAD(crypto_key_parsers); + DECLARE_RWSEM(crypto_key_parsers_sem); + + /* diff --git a/security/keys/crypto/crypto_verify.c b/security/keys/crypto/crypto_verify.c new file mode 100644 -index 0000000..3f2964b +index 0000000..d64f1c7 --- /dev/null +++ b/security/keys/crypto/crypto_verify.c -@@ -0,0 +1,112 @@ +@@ -0,0 +1,159 @@ +/* Signature verification with a crypto key + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -1264,6 +2295,8 @@ index 0000000..3f2964b +#include +#include "crypto_keys.h" + ++static LIST_HEAD(crypto_sig_parsers); ++ +/** + * verify_sig_begin - Initiate the use of a crypto key to verify a signature + * @keyring: The public keys to verify against @@ -1272,11 +2305,11 @@ index 0000000..3f2964b + * + * Returns a context or an error. + */ -+struct crypto_key_verify_context *verify_sig_begin( ++struct crypto_sig_verify_context *verify_sig_begin( + struct key *keyring, const void *sig, size_t siglen) +{ -+ struct crypto_key_verify_context *ret; -+ struct crypto_key_parser *parser; ++ struct crypto_sig_verify_context *ret; ++ struct crypto_sig_parser *parser; + + pr_devel("==>%s()\n", __func__); + @@ -1286,7 +2319,7 @@ index 0000000..3f2964b + down_read(&crypto_key_parsers_sem); + + ret = ERR_PTR(-EBADMSG); -+ list_for_each_entry(parser, &crypto_key_parsers, link) { ++ list_for_each_entry(parser, &crypto_sig_parsers, link) { + if (parser->verify_sig_begin) { + if (!try_module_get(parser->owner)) + continue; @@ -1321,7 +2354,7 @@ index 0000000..3f2964b + * + * This may be called multiple times. + */ -+int verify_sig_add_data(struct crypto_key_verify_context *ctx, ++int verify_sig_add_data(struct crypto_sig_verify_context *ctx, + const void *data, size_t datalen) +{ + return ctx->add_data(ctx, data, datalen); @@ -1334,10 +2367,10 @@ index 0000000..3f2964b + * @sig: The signature data + * @siglen: The signature length + */ -+int verify_sig_end(struct crypto_key_verify_context *ctx, ++int verify_sig_end(struct crypto_sig_verify_context *ctx, + const void *sig, size_t siglen) +{ -+ struct crypto_key_parser *parser = ctx->parser; ++ struct crypto_sig_parser *parser = ctx->parser; + int ret; + + ret = ctx->end(ctx, sig, siglen); @@ -1350,22 +2383,67 @@ index 0000000..3f2964b + * verify_sig_end - Cancel signature verification + * @ctx: The context from verify_sig_begin() + */ -+void verify_sig_cancel(struct crypto_key_verify_context *ctx) ++void verify_sig_cancel(struct crypto_sig_verify_context *ctx) +{ -+ struct crypto_key_parser *parser = ctx->parser; ++ struct crypto_sig_parser *parser = ctx->parser; + + ctx->cancel(ctx); + module_put(parser->owner); +} +EXPORT_SYMBOL_GPL(verify_sig_cancel); ++ ++/** ++ * register_crypto_sig_parser - Register a crypto sig blob parser ++ * @parser: The parser to register ++ */ ++int register_crypto_sig_parser(struct crypto_sig_parser *parser) ++{ ++ struct crypto_sig_parser *cursor; ++ int ret; ++ ++ down_write(&crypto_key_parsers_sem); ++ ++ list_for_each_entry(cursor, &crypto_sig_parsers, link) { ++ if (strcmp(cursor->name, parser->name) == 0) { ++ pr_err("Crypto signature parser '%s' already registered\n", ++ parser->name); ++ ret = -EEXIST; ++ goto out; ++ } ++ } ++ ++ list_add_tail(&parser->link, &crypto_sig_parsers); ++ ++ pr_notice("Crypto signature parser '%s' registered\n", parser->name); ++ ret = 0; ++ ++out: ++ up_write(&crypto_key_parsers_sem); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(register_crypto_sig_parser); ++ ++/** ++ * unregister_crypto_sig_parser - Unregister a crypto sig blob parser ++ * @parser: The parser to unregister ++ */ ++void unregister_crypto_sig_parser(struct crypto_sig_parser *parser) ++{ ++ down_write(&crypto_key_parsers_sem); ++ list_del(&parser->link); ++ up_write(&crypto_key_parsers_sem); ++ ++ pr_notice("Crypto signature parser '%s' unregistered\n", parser->name); ++} ++EXPORT_SYMBOL_GPL(unregister_crypto_sig_parser); -- -1.7.11.2 +1.7.11.4 -From a0fe6700fba7b7497cf137dc6a969d299ee59c67 Mon Sep 17 00:00:00 2001 +From d8cb66a6f69869c8c2992f67915a7c238066f2fb Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 13:59:52 +0100 -Subject: [PATCH 04/28] KEYS: Asymmetric public-key algorithm crypto key +Date: Thu, 16 Aug 2012 00:14:18 +0100 +Subject: [PATCH 05/32] KEYS: Asymmetric public-key algorithm crypto key subtype Add a subtype for supporting asymmetric public-key encryption algorithms such @@ -1375,9 +2453,9 @@ Signed-off-by: David Howells --- security/keys/crypto/Kconfig | 10 ++++ security/keys/crypto/Makefile | 3 +- - security/keys/crypto/public_key.c | 55 ++++++++++++++++++++ - security/keys/crypto/public_key.h | 106 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 173 insertions(+), 1 deletion(-) + security/keys/crypto/public_key.c | 82 +++++++++++++++++++++++++ + security/keys/crypto/public_key.h | 123 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 security/keys/crypto/public_key.c create mode 100644 security/keys/crypto/public_key.h @@ -1413,10 +2491,10 @@ index 67001bc..6384306 100644 +obj-$(CONFIG_CRYPTO_KEY_PUBLIC_KEY_SUBTYPE) += public_key.o diff --git a/security/keys/crypto/public_key.c b/security/keys/crypto/public_key.c new file mode 100644 -index 0000000..c00ddac +index 0000000..ebb31ec --- /dev/null +++ b/security/keys/crypto/public_key.c -@@ -0,0 +1,55 @@ +@@ -0,0 +1,82 @@ +/* Asymmetric public key crypto subtype + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -1430,11 +2508,36 @@ index 0000000..c00ddac + +#define pr_fmt(fmt) "PKEY: "fmt +#include ++#include +#include +#include "public_key.h" + +MODULE_LICENSE("GPL"); + ++const char *const pkey_algo[PKEY_ALGO__LAST] = { ++ [PKEY_ALGO_DSA] = "DSA", ++ [PKEY_ALGO_RSA] = "RSA", ++}; ++EXPORT_SYMBOL_GPL(pkey_algo); ++ ++const char *const pkey_hash_algo[PKEY_HASH__LAST] = { ++ [PKEY_HASH_MD4] = "md4", ++ [PKEY_HASH_MD5] = "md5", ++ [PKEY_HASH_SHA1] = "sha1", ++ [PKEY_HASH_RIPE_MD_160] = "rmd160", ++ [PKEY_HASH_SHA256] = "sha256", ++ [PKEY_HASH_SHA384] = "sha384", ++ [PKEY_HASH_SHA512] = "sha512", ++ [PKEY_HASH_SHA224] = "sha224", ++}; ++EXPORT_SYMBOL_GPL(pkey_hash_algo); ++ ++const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = { ++ [PKEY_ID_PGP] = "PGP", ++ [PKEY_ID_X509] = "X509", ++}; ++EXPORT_SYMBOL_GPL(pkey_id_type); ++ +/* + * Provide a part of a description of the key for /proc/keys. + */ @@ -1444,13 +2547,14 @@ index 0000000..c00ddac + struct public_key *key = crypto_key->payload.data; + + if (key) -+ seq_puts(m, key->algo->name); ++ seq_printf(m, "%s.%s", ++ pkey_id_type[key->id_type], key->algo->name); +} + +/* + * Destroy a public key algorithm key + */ -+static void public_key_destroy(void *payload) ++void public_key_destroy(void *payload) +{ + struct public_key *key = payload; + int i; @@ -1461,6 +2565,7 @@ index 0000000..c00ddac + kfree(key); + } +} ++EXPORT_SYMBOL_GPL(public_key_destroy); + +/* + * Public key algorithm crypto key subtype @@ -1474,10 +2579,10 @@ index 0000000..c00ddac +EXPORT_SYMBOL_GPL(public_key_crypto_key_subtype); diff --git a/security/keys/crypto/public_key.h b/security/keys/crypto/public_key.h new file mode 100644 -index 0000000..81ed603 +index 0000000..228090d --- /dev/null +++ b/security/keys/crypto/public_key.h -@@ -0,0 +1,106 @@ +@@ -0,0 +1,123 @@ +/* Asymmetric public-key algorithm definitions + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -1499,7 +2604,16 @@ index 0000000..81ed603 +struct public_key; +struct public_key_signature; + ++enum pkey_algo { ++ PKEY_ALGO_DSA, ++ PKEY_ALGO_RSA, ++ PKEY_ALGO__LAST ++}; ++ ++extern const char *const pkey_algo[PKEY_ALGO__LAST]; ++ +enum pkey_hash_algo { ++ PKEY_HASH_MD4, + PKEY_HASH_MD5, + PKEY_HASH_SHA1, + PKEY_HASH_RIPE_MD_160, @@ -1510,6 +2624,16 @@ index 0000000..81ed603 + PKEY_HASH__LAST +}; + ++extern const char *const pkey_hash_algo[PKEY_HASH__LAST]; ++ ++enum pkey_id_type { ++ PKEY_ID_PGP, /* OpenPGP generated key ID */ ++ PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ ++ PKEY_ID_TYPE__LAST ++}; ++ ++extern const char *const pkey_id_type[PKEY_ID_TYPE__LAST]; ++ +/* + * Public key type definition + */ @@ -1534,6 +2658,7 @@ index 0000000..81ed603 +#define PKEY_CAN_SIGN 0x04 +#define PKEY_CAN_VERIFY 0x08 +#define PKEY_CAN_SIGVER (PKEY_CAN_SIGN | PKEY_CAN_VERIFY) ++ enum pkey_id_type id_type : 8; + union { + MPI mpi[5]; + struct { @@ -1560,7 +2685,7 @@ index 0000000..81ed603 + * Asymmetric public key algorithm signature data + */ +struct public_key_signature { -+ struct crypto_key_verify_context base; ++ struct crypto_sig_verify_context base; + u8 *digest; + enum pkey_hash_algo pkey_hash_algo : 8; + u8 signed_hash_msw[2]; @@ -1578,20 +2703,17 @@ index 0000000..81ed603 + struct shash_desc hash; /* This must go last! */ +}; + -+extern struct crypto_key_verify_context *pgp_pkey_verify_sig_begin( -+ struct key *crypto_key, const u8 *sigdata, size_t siglen); -+ +extern struct crypto_key_subtype public_key_crypto_key_subtype; + +#endif /* _LINUX_PUBLIC_KEY_H */ -- -1.7.11.2 +1.7.11.4 -From 39eaf7c28e0ca07dcb5e1e2a12db62815890f0e7 Mon Sep 17 00:00:00 2001 +From 76b6843d2be046bd5ab8fbae8a1cc5b5d2d48a80 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:10:37 +0100 -Subject: [PATCH 05/28] MPILIB: Reinstate mpi_cmp[_ui]() and export for RSA +Date: Thu, 16 Aug 2012 00:14:18 +0100 +Subject: [PATCH 06/32] MPILIB: Reinstate mpi_cmp[_ui]() and export for RSA signature verification Reinstate and export mpi_cmp() and mpi_cmp_ui() from the MPI library for use by @@ -1693,13 +2815,13 @@ index 0000000..1871e7b +} +EXPORT_SYMBOL_GPL(mpi_cmp); -- -1.7.11.2 +1.7.11.4 -From c995ac0765cfffe9b293327717e080c2cd253779 Mon Sep 17 00:00:00 2001 +From 48c4be1c886e51edbbbebdb65421a7ca120a8d21 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:10:39 +0100 -Subject: [PATCH 06/28] KEYS: RSA: Implement signature verification algorithm +Date: Thu, 16 Aug 2012 00:14:18 +0100 +Subject: [PATCH 07/32] KEYS: RSA: Implement signature verification algorithm [PKCS#1 / RFC3447] Implement RSA public key cryptography [PKCS#1 / RFC3447]. At this time, only @@ -1710,9 +2832,9 @@ Signed-off-by: David Howells --- security/keys/crypto/Kconfig | 7 + security/keys/crypto/Makefile | 1 + - security/keys/crypto/crypto_rsa.c | 264 ++++++++++++++++++++++++++++++++++++++ + security/keys/crypto/crypto_rsa.c | 267 ++++++++++++++++++++++++++++++++++++++ security/keys/crypto/public_key.h | 2 + - 4 files changed, 274 insertions(+) + 4 files changed, 277 insertions(+) create mode 100644 security/keys/crypto/crypto_rsa.c diff --git a/security/keys/crypto/Kconfig b/security/keys/crypto/Kconfig @@ -1741,10 +2863,10 @@ index 6384306..b6b1a5a 100644 +obj-$(CONFIG_CRYPTO_KEY_PKEY_ALGO_RSA) += crypto_rsa.o diff --git a/security/keys/crypto/crypto_rsa.c b/security/keys/crypto/crypto_rsa.c new file mode 100644 -index 0000000..845285c +index 0000000..6e95e60 --- /dev/null +++ b/security/keys/crypto/crypto_rsa.c -@@ -0,0 +1,264 @@ +@@ -0,0 +1,267 @@ +/* RSA asymmetric public-key algorithm [RFC3447] + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -1965,6 +3087,9 @@ index 0000000..845285c + + kenter(""); + ++ if (!RSA_ASN1_templates[sig->pkey_hash_algo].data) ++ return -ENOTSUPP; ++ + /* (1) Check the signature size against the public key modulus size */ + k = (mpi_get_nbits(key->rsa.n) + 7) / 8; + @@ -2010,10 +3135,10 @@ index 0000000..845285c +}; +EXPORT_SYMBOL_GPL(RSA_public_key_algorithm); diff --git a/security/keys/crypto/public_key.h b/security/keys/crypto/public_key.h -index 81ed603..7913615 100644 +index 228090d..947817b 100644 --- a/security/keys/crypto/public_key.h +++ b/security/keys/crypto/public_key.h -@@ -42,6 +42,8 @@ struct public_key_algorithm { +@@ -61,6 +61,8 @@ struct public_key_algorithm { const struct public_key_signature *sig); }; @@ -2023,13 +3148,13 @@ index 81ed603..7913615 100644 * Asymmetric public key data */ -- -1.7.11.2 +1.7.11.4 -From d9acf3806acdc9ab5e26a1c604989070a7ae6840 Mon Sep 17 00:00:00 2001 +From 311305a6e970236bd30d8942552a26e6f93730ce Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:19 +0100 -Subject: [PATCH 07/28] KEYS: RSA: Fix signature verification for shorter +Date: Thu, 16 Aug 2012 00:14:19 +0100 +Subject: [PATCH 08/32] KEYS: RSA: Fix signature verification for shorter signatures gpg can produce a signature file where length of signature is less than the @@ -2048,11 +3173,11 @@ Signed-off-by: David Howells 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/security/keys/crypto/crypto_rsa.c b/security/keys/crypto/crypto_rsa.c -index 845285c..a4a63be 100644 +index 6e95e60..796ed1d 100644 --- a/security/keys/crypto/crypto_rsa.c +++ b/security/keys/crypto/crypto_rsa.c -@@ -219,15 +219,23 @@ static int RSA_verify_signature(const struct public_key *key, - kenter(""); +@@ -222,15 +222,23 @@ static int RSA_verify_signature(const struct public_key *key, + return -ENOTSUPP; /* (1) Check the signature size against the public key modulus size */ - k = (mpi_get_nbits(key->rsa.n) + 7) / 8; @@ -2079,13 +3204,13 @@ index 845285c..a4a63be 100644 ret = RSAVP1(key, sig->rsa.s, &m); if (ret < 0) -- -1.7.11.2 +1.7.11.4 -From 9a2a2b1faa27be883b3aa2c47bbc367bd1a1f653 Mon Sep 17 00:00:00 2001 +From a9b954d2c225dc99ecc319ea760576f525f0a623 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:19 +0100 -Subject: [PATCH 08/28] PGPLIB: PGP definitions (RFC 4880) +Date: Thu, 16 Aug 2012 00:14:19 +0100 +Subject: [PATCH 09/32] PGPLIB: PGP definitions (RFC 4880) Provide some useful PGP definitions from RFC 4880. These describe details of public key crypto as used by crypto keys for things like signature @@ -2310,13 +3435,13 @@ index 0000000..1359f64 + +#endif /* _LINUX_PGP_H */ -- -1.7.11.2 +1.7.11.4 -From 0b8ec95fe7220288c143a820b8d8996c356129f1 Mon Sep 17 00:00:00 2001 +From 1937e5a7e8ae1abdb7f1dc72f7b128e33c31d644 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:20 +0100 -Subject: [PATCH 09/28] PGPLIB: Basic packet parser +Date: Thu, 16 Aug 2012 01:33:13 +0100 +Subject: [PATCH 10/32] PGPLIB: Basic packet parser Provide a simple parser that extracts the packets from a PGP packet blob and passes the desirous ones to the given processor function: @@ -2423,7 +3548,7 @@ index b6b1a5a..5fbe54e 100644 +obj-$(CONFIG_PGP_LIBRARY) += pgp_library.o diff --git a/security/keys/crypto/pgp_library.c b/security/keys/crypto/pgp_library.c new file mode 100644 -index 0000000..af396d6 +index 0000000..39d2878 --- /dev/null +++ b/security/keys/crypto/pgp_library.c @@ -0,0 +1,268 @@ @@ -2477,7 +3602,7 @@ index 0000000..af396d6 + const u8 *data = *_data; + size_t size, datalen = *_datalen; + -+ pr_devel("-->pgp_parse_packet_header(,%zu,,)", datalen); ++ pr_devel("-->pgp_parse_packet_header(,%zu,,)\n", datalen); + + if (datalen < 2) + goto short_packet; @@ -2696,13 +3821,13 @@ index 0000000..af396d6 +} +EXPORT_SYMBOL_GPL(pgp_parse_public_key); -- -1.7.11.2 +1.7.11.4 -From a3673ac73f4634bcdd97d642b3bdd87998eb2100 Mon Sep 17 00:00:00 2001 +From 3379efc21d2ecc93de135e3265baabbe1f326d5a Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:20 +0100 -Subject: [PATCH 10/28] PGPLIB: Signature parser +Date: Thu, 16 Aug 2012 01:33:17 +0100 +Subject: [PATCH 11/32] PGPLIB: Signature parser Provide some PGP signature parsing helpers: @@ -2761,7 +3886,7 @@ index a045b3a..34594a9 100644 #endif /* CONFIG_PGP_LIBRARY */ diff --git a/security/keys/crypto/pgp_library.c b/security/keys/crypto/pgp_library.c -index af396d6..c9218df 100644 +index 39d2878..50b7fa0 100644 --- a/security/keys/crypto/pgp_library.c +++ b/security/keys/crypto/pgp_library.c @@ -266,3 +266,283 @@ int pgp_parse_public_key(const u8 **_data, size_t *_datalen, @@ -3049,13 +4174,13 @@ index af396d6..c9218df 100644 +} +EXPORT_SYMBOL_GPL(pgp_parse_sig_params); -- -1.7.11.2 +1.7.11.4 -From dd59f49ce7179b145f55bdca3b43f4761ae0769d Mon Sep 17 00:00:00 2001 +From 39b6dd66338812a1e1806489d3fed50620011b14 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:21 +0100 -Subject: [PATCH 11/28] KEYS: PGP data parser +Date: Thu, 16 Aug 2012 01:33:17 +0100 +Subject: [PATCH 12/32] KEYS: PGP data parser Implement a PGP data parser for the crypto key type to use when instantiating a key. @@ -3075,8 +4200,8 @@ Signed-off-by: David Howells security/keys/crypto/Kconfig | 12 ++ security/keys/crypto/Makefile | 4 + security/keys/crypto/pgp_parser.h | 23 +++ - security/keys/crypto/pgp_public_key.c | 348 ++++++++++++++++++++++++++++++++++ - 4 files changed, 387 insertions(+) + security/keys/crypto/pgp_public_key.c | 344 ++++++++++++++++++++++++++++++++++ + 4 files changed, 383 insertions(+) create mode 100644 security/keys/crypto/pgp_parser.h create mode 100644 security/keys/crypto/pgp_public_key.c @@ -3143,10 +4268,10 @@ index 0000000..1cda231 +struct public_key_algorithm *pgp_public_key_algorithms[PGP_PUBKEY__LAST]; diff --git a/security/keys/crypto/pgp_public_key.c b/security/keys/crypto/pgp_public_key.c new file mode 100644 -index 0000000..8a8b7c0 +index 0000000..c260e02 --- /dev/null +++ b/security/keys/crypto/pgp_public_key.c -@@ -0,0 +1,348 @@ +@@ -0,0 +1,344 @@ +/* Instantiate a public key crypto key from PGP format data [RFC 4880] + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -3328,6 +4453,7 @@ index 0000000..8a8b7c0 + + memcpy(&key->key_id, raw_fingerprint + offset, 8); + key->key_id_size = 8; ++ key->id_type = PKEY_ID_PGP; + + ctx->fingerprint = fingerprint; + ret = 0; @@ -3438,18 +4564,13 @@ index 0000000..8a8b7c0 + * Attempt to parse the instantiation data blob for a key as a PGP packet + * message holding a key. + */ -+static int pgp_key_instantiate(struct key *key, -+ const void *data, size_t datalen) ++static int pgp_key_preparse(struct key_preparsed_payload *prep) +{ + struct pgp_key_data_parse_context ctx; + int ret; + + kenter(""); + -+ ret = key_payload_reserve(key, datalen); -+ if (ret < 0) -+ return ret; -+ + ctx.pgp.types_of_interest = + (1 << PGP_PKT_PUBLIC_KEY) | (1 << PGP_PKT_PUBLIC_SUBKEY); + ctx.pgp.process_packet = pgp_process_public_key; @@ -3457,27 +4578,27 @@ index 0000000..8a8b7c0 + ctx.fingerprint = NULL; + ctx.payload = NULL; + -+ ret = pgp_parse_packets(data, datalen, &ctx.pgp); ++ ret = pgp_parse_packets(prep->data, prep->datalen, &ctx.pgp); + if (ret < 0) { + if (ctx.payload) + ctx.subtype->destroy(ctx.payload); + if (ctx.subtype) + module_put(ctx.subtype->owner); + kfree(ctx.fingerprint); -+ key_payload_reserve(key, 0); + return ret; + } + -+ key->type_data.p[0] = ctx.subtype; -+ key->type_data.p[1] = ctx.fingerprint; -+ key->payload.data = ctx.payload; ++ prep->type_data[0] = ctx.subtype; ++ prep->type_data[1] = ctx.fingerprint; ++ prep->payload = ctx.payload; ++ prep->quotalen = prep->datalen; + return 0; +} + +static struct crypto_key_parser pgp_key_parser = { + .owner = THIS_MODULE, + .name = "pgp", -+ .instantiate = pgp_key_instantiate, ++ .preparse = pgp_key_preparse, +}; + +/* @@ -3496,13 +4617,13 @@ index 0000000..8a8b7c0 +module_init(pgp_key_init); +module_exit(pgp_key_exit); -- -1.7.11.2 +1.7.11.4 -From 80437db0342877f06d689d33babcc99175d34b82 Mon Sep 17 00:00:00 2001 +From 1095ff02a49868cf8f3706dd2c83474bcf2081f8 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:21 +0100 -Subject: [PATCH 12/28] KEYS: PGP-based public key signature verification +Date: Thu, 16 Aug 2012 01:33:17 +0100 +Subject: [PATCH 13/32] KEYS: PGP-based public key signature verification Provide handlers for PGP-based public-key algorithm signature verification. This does most of the work involved in signature verification as most of it is @@ -3532,7 +4653,7 @@ index 35733fc..0c8b8a1 100644 + pgp_public_key.o \ + pgp_sig_verify.o diff --git a/security/keys/crypto/pgp_parser.h b/security/keys/crypto/pgp_parser.h -index 1cda231..a6192ce 100644 +index 1cda231..6f5b3af 100644 --- a/security/keys/crypto/pgp_parser.h +++ b/security/keys/crypto/pgp_parser.h @@ -21,3 +21,9 @@ @@ -3543,11 +4664,11 @@ index 1cda231..a6192ce 100644 +/* + * pgp_pubkey_sig.c + */ -+extern struct crypto_key_verify_context *pgp_pkey_verify_sig_begin( ++extern struct crypto_sig_verify_context *pgp_pkey_verify_sig_begin( + struct key *crypto_key, const u8 *sigdata, size_t siglen); diff --git a/security/keys/crypto/pgp_sig_verify.c b/security/keys/crypto/pgp_sig_verify.c new file mode 100644 -index 0000000..82c89da +index 0000000..f9bb949 --- /dev/null +++ b/security/keys/crypto/pgp_sig_verify.c @@ -0,0 +1,325 @@ @@ -3583,11 +4704,11 @@ index 0000000..82c89da + [PGP_HASH_SHA224].algo = PKEY_HASH_SHA224, +}; + -+static int pgp_pkey_verify_sig_add_data(struct crypto_key_verify_context *ctx, ++static int pgp_pkey_verify_sig_add_data(struct crypto_sig_verify_context *ctx, + const void *data, size_t datalen); -+static int pgp_pkey_verify_sig_end(struct crypto_key_verify_context *ctx, ++static int pgp_pkey_verify_sig_end(struct crypto_sig_verify_context *ctx, + const u8 *sig, size_t siglen); -+static void pgp_pkey_verify_sig_cancel(struct crypto_key_verify_context *ctx); ++static void pgp_pkey_verify_sig_cancel(struct crypto_sig_verify_context *ctx); + +struct pgp_pkey_sig_parse_context { + struct pgp_parse_context pgp; @@ -3613,7 +4734,7 @@ index 0000000..82c89da + * metadata will be put, and parsing the signature to check that it matches the + * key. + */ -+struct crypto_key_verify_context *pgp_pkey_verify_sig_begin( ++struct crypto_sig_verify_context *pgp_pkey_verify_sig_begin( + struct key *crypto_key, const u8 *sigdata, size_t siglen) +{ + struct pgp_pkey_sig_parse_context p; @@ -3720,7 +4841,7 @@ index 0000000..82c89da +/* + * Load data into the hash + */ -+static int pgp_pkey_verify_sig_add_data(struct crypto_key_verify_context *ctx, ++static int pgp_pkey_verify_sig_add_data(struct crypto_sig_verify_context *ctx, + const void *data, size_t datalen) +{ + struct public_key_signature *sig = @@ -3825,7 +4946,7 @@ index 0000000..82c89da + * The data is now all loaded into the hash; load the metadata, finalise the + * hash and perform the verification step. + */ -+static int pgp_pkey_verify_sig_end(struct crypto_key_verify_context *ctx, ++static int pgp_pkey_verify_sig_end(struct crypto_sig_verify_context *ctx, + const u8 *sigdata, size_t siglen) +{ + struct public_key_signature *sig = @@ -3859,7 +4980,7 @@ index 0000000..82c89da +/* + * Cancel an in-progress data loading + */ -+static void pgp_pkey_verify_sig_cancel(struct crypto_key_verify_context *ctx) ++static void pgp_pkey_verify_sig_cancel(struct crypto_sig_verify_context *ctx) +{ + struct public_key_signature *sig = + container_of(ctx, struct public_key_signature, base); @@ -3877,13 +4998,13 @@ index 0000000..82c89da + kleave(""); +} -- -1.7.11.2 +1.7.11.4 -From 1826f7b562237c008c66ad63b7d7d4c7c44b98fb Mon Sep 17 00:00:00 2001 +From 69d9f31b888090b5705b7148760143a6b706a116 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:21 +0100 -Subject: [PATCH 13/28] KEYS: PGP format signature parser +Date: Thu, 16 Aug 2012 01:33:17 +0100 +Subject: [PATCH 14/32] KEYS: PGP format signature parser Implement a signature parser that will attempt to parse a signature blob as a PGP packet format message. If it can, it will find an appropriate crypto key @@ -3892,10 +5013,8 @@ and set the public-key algorithm according to the data in the signature. Signed-off-by: David Howells --- security/keys/crypto/Makefile | 1 + - security/keys/crypto/pgp_parser.h | 6 ++ - security/keys/crypto/pgp_public_key.c | 1 + - security/keys/crypto/pgp_sig_parser.c | 114 ++++++++++++++++++++++++++++++++++ - 4 files changed, 122 insertions(+) + security/keys/crypto/pgp_sig_parser.c | 136 ++++++++++++++++++++++++++++++++++ + 2 files changed, 137 insertions(+) create mode 100644 security/keys/crypto/pgp_sig_parser.c diff --git a/security/keys/crypto/Makefile b/security/keys/crypto/Makefile @@ -3908,41 +5027,12 @@ index 0c8b8a1..a9a34c6 100644 pgp_public_key.o \ + pgp_sig_parser.o \ pgp_sig_verify.o -diff --git a/security/keys/crypto/pgp_parser.h b/security/keys/crypto/pgp_parser.h -index a6192ce..73c900e 100644 ---- a/security/keys/crypto/pgp_parser.h -+++ b/security/keys/crypto/pgp_parser.h -@@ -23,6 +23,12 @@ extern const - struct public_key_algorithm *pgp_public_key_algorithms[PGP_PUBKEY__LAST]; - - /* -+ * pgp_sig_parser.c -+ */ -+extern struct crypto_key_verify_context *pgp_verify_sig_begin( -+ struct key *keyring, const u8 *sig, size_t siglen); -+ -+/* - * pgp_pubkey_sig.c - */ - extern struct crypto_key_verify_context *pgp_pkey_verify_sig_begin( -diff --git a/security/keys/crypto/pgp_public_key.c b/security/keys/crypto/pgp_public_key.c -index 8a8b7c0..5ab926d 100644 ---- a/security/keys/crypto/pgp_public_key.c -+++ b/security/keys/crypto/pgp_public_key.c -@@ -329,6 +329,7 @@ static struct crypto_key_parser pgp_key_parser = { - .owner = THIS_MODULE, - .name = "pgp", - .instantiate = pgp_key_instantiate, -+ .verify_sig_begin = pgp_verify_sig_begin, - }; - - /* diff --git a/security/keys/crypto/pgp_sig_parser.c b/security/keys/crypto/pgp_sig_parser.c new file mode 100644 -index 0000000..f5feb2b +index 0000000..683eb53 --- /dev/null +++ b/security/keys/crypto/pgp_sig_parser.c -@@ -0,0 +1,114 @@ +@@ -0,0 +1,136 @@ +/* Handling for PGP public key signature data [RFC 4880] + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -4042,10 +5132,10 @@ index 0000000..f5feb2b + * Attempt to parse a signature as a PGP packet format blob and find a + * matching key. + */ -+struct crypto_key_verify_context *pgp_verify_sig_begin( ++static struct crypto_sig_verify_context *pgp_verify_sig_begin( + struct key *keyring, const u8 *sig, size_t siglen) +{ -+ struct crypto_key_verify_context *ctx; ++ struct crypto_sig_verify_context *ctx; + struct key *key; + + key = find_key_for_pgp_sig(keyring, sig, siglen); @@ -4057,14 +5147,169 @@ index 0000000..f5feb2b + key_put(key); + return ctx; +} ++ ++static struct crypto_sig_parser pgp_sig_parser = { ++ .owner = THIS_MODULE, ++ .name = "pgp", ++ .verify_sig_begin = pgp_verify_sig_begin, ++}; ++ ++/* ++ * Module stuff ++ */ ++static int __init pgp_sig_init(void) ++{ ++ return register_crypto_sig_parser(&pgp_sig_parser); ++} ++ ++static void __exit pgp_sig_exit(void) ++{ ++ unregister_crypto_sig_parser(&pgp_sig_parser); ++} ++ ++module_init(pgp_sig_init); ++module_exit(pgp_sig_exit); -- -1.7.11.2 +1.7.11.4 -From 68b4585107d4d014b4de3536c972c63f617c48f5 Mon Sep 17 00:00:00 2001 +From fe109b5adbb22b3503cb1f72f5585543218ba990 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:11:21 +0100 -Subject: [PATCH 14/28] KEYS: Provide a function to load keys from a PGP +Date: Thu, 16 Aug 2012 01:33:17 +0100 +Subject: [PATCH 15/32] KEYS: Provide PGP key description autogeneration + +Provide a facility to autogenerate the name of PGP keys from the contents of +the payload. If add_key() is given a blank description, a description is +constructed from the last user ID packet in the payload data plus the last 8 +hex digits of the key ID. For instance: + + keyctl padd crypto "" @s +--- + security/keys/crypto/pgp_public_key.c | 64 +++++++++++++++++++++++++++++------ + 1 file changed, 53 insertions(+), 11 deletions(-) + +diff --git a/security/keys/crypto/pgp_public_key.c b/security/keys/crypto/pgp_public_key.c +index c260e02..2347ecd 100644 +--- a/security/keys/crypto/pgp_public_key.c ++++ b/security/keys/crypto/pgp_public_key.c +@@ -52,6 +52,9 @@ struct pgp_key_data_parse_context { + struct crypto_key_subtype *subtype; + char *fingerprint; + void *payload; ++ const char *user_id; ++ size_t user_id_len; ++ size_t fingerprint_len; + }; + + /* +@@ -166,6 +169,7 @@ static int pgp_generate_fingerprint(struct pgp_key_data_parse_context *ctx, + if (ret < 0) + goto cleanup_raw_fingerprint; + ++ ctx->fingerprint_len = digest_size * 2; + fingerprint = kmalloc(digest_size * 2 + 1, GFP_KERNEL); + if (!fingerprint) + goto cleanup_raw_fingerprint; +@@ -212,6 +216,13 @@ static int pgp_process_public_key(struct pgp_parse_context *context, + + kenter(",%u,%u,,%zu", type, headerlen, datalen); + ++ if (type == PGP_PKT_USER_ID) { ++ ctx->user_id = data; ++ ctx->user_id_len = datalen; ++ kleave(" = 0 [user ID]"); ++ return 0; ++ } ++ + if (ctx->subtype) { + kleave(" = -ENOKEY [already]"); + return -EBADMSG; +@@ -297,21 +308,44 @@ static int pgp_key_preparse(struct key_preparsed_payload *prep) + + kenter(""); + ++ memset(&ctx, 0, sizeof(ctx)); + ctx.pgp.types_of_interest = +- (1 << PGP_PKT_PUBLIC_KEY) | (1 << PGP_PKT_PUBLIC_SUBKEY); ++ (1 << PGP_PKT_PUBLIC_KEY) | (1 << PGP_PKT_PUBLIC_SUBKEY) | ++ (1 << PGP_PKT_USER_ID); + ctx.pgp.process_packet = pgp_process_public_key; +- ctx.subtype = NULL; +- ctx.fingerprint = NULL; +- ctx.payload = NULL; + + ret = pgp_parse_packets(prep->data, prep->datalen, &ctx.pgp); +- if (ret < 0) { +- if (ctx.payload) +- ctx.subtype->destroy(ctx.payload); +- if (ctx.subtype) +- module_put(ctx.subtype->owner); +- kfree(ctx.fingerprint); +- return ret; ++ if (ret < 0) ++ goto error; ++ ++ if (ctx.user_id && ctx.user_id_len > 0) { ++ /* Propose a description for the key (user ID without the comment) */ ++ size_t ulen = ctx.user_id_len, flen = ctx.fingerprint_len; ++ const char *p; ++ ++ p = memchr(ctx.user_id, '(', ulen); ++ if (p) { ++ /* Remove the comment */ ++ do { ++ p--; ++ } while (*p == ' ' && p > ctx.user_id); ++ if (*p != ' ') ++ p++; ++ ulen = p - ctx.user_id; ++ } ++ ++ if (ulen > 255 - 9) ++ ulen = 255 - 9; ++ prep->description = kmalloc(ulen + 1 + 8 + 1, GFP_KERNEL); ++ ret = -ENOMEM; ++ if (!prep->description) ++ goto error; ++ memcpy(prep->description, ctx.user_id, ulen); ++ prep->description[ulen] = ' '; ++ memcpy(prep->description + ulen + 1, ++ ctx.fingerprint + flen - 8, 8); ++ prep->description[ulen + 9] = 0; ++ pr_debug("desc '%s'\n", prep->description); + } + + prep->type_data[0] = ctx.subtype; +@@ -319,6 +353,14 @@ static int pgp_key_preparse(struct key_preparsed_payload *prep) + prep->payload = ctx.payload; + prep->quotalen = prep->datalen; + return 0; ++ ++error: ++ if (ctx.payload) ++ ctx.subtype->destroy(ctx.payload); ++ if (ctx.subtype) ++ module_put(ctx.subtype->owner); ++ kfree(ctx.fingerprint); ++ return ret; + } + + static struct crypto_key_parser pgp_key_parser = { +-- +1.7.11.4 + + +From 77b00423d002eb013293177310644c8284b6ea2f Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Thu, 16 Aug 2012 01:33:18 +0100 +Subject: [PATCH 16/32] KEYS: Provide a function to load keys from a PGP keyring blob Provide a function to load keys from a PGP keyring blob for use in initialising @@ -4089,16 +5334,16 @@ out some errors. Signed-off-by: David Howells --- - Documentation/security/keys-crypto.txt | 20 +++++++ - include/keys/crypto-type.h | 3 ++ - security/keys/crypto/Kconfig | 9 ++++ - security/keys/crypto/Makefile | 1 + - security/keys/crypto/pgp_preload.c | 96 ++++++++++++++++++++++++++++++++++ - 5 files changed, 129 insertions(+) + Documentation/security/keys-crypto.txt | 20 ++++++ + include/keys/crypto-type.h | 3 + + security/keys/crypto/Kconfig | 9 +++ + security/keys/crypto/Makefile | 1 + + security/keys/crypto/pgp_preload.c | 115 +++++++++++++++++++++++++++++++++ + 5 files changed, 148 insertions(+) create mode 100644 security/keys/crypto/pgp_preload.c diff --git a/Documentation/security/keys-crypto.txt b/Documentation/security/keys-crypto.txt -index a964717..ba2ab55 100644 +index 0a886ec..be5067e 100644 --- a/Documentation/security/keys-crypto.txt +++ b/Documentation/security/keys-crypto.txt @@ -10,6 +10,7 @@ Contents: @@ -4109,7 +5354,7 @@ index a964717..ba2ab55 100644 ======== -@@ -280,3 +281,22 @@ There are a number of operations defined by the subtype: +@@ -279,3 +280,22 @@ There are a number of operations defined by the subtype: Mandatory. This should free the memory associated with the key. The crypto key will look after freeing the fingerprint and releasing the reference on the subtype module. @@ -4123,25 +5368,25 @@ index a964717..ba2ab55 100644 +into a PGP packet format blob: + + int preload_pgp_keys(const u8 *pgpdata, size_t pgpdatalen, -+ struct key *keyring, const char *descprefix); ++ struct key *keyring); + +This takes the blob of data defined by pgpdata and pgpdatalen, extracts keys -+from them and adds them to the specified keyring. The keys are labelled with -+descprefix plus a simple uniquifier - it is not expected that the description -+will be used to identify the key. The description is required to prevent all -+but the last key being discarded when the keys are linked into the keyring. ++from them and adds them to the specified keyring. The keys are labelled with a ++description generated from the fingerprint and last user ID of each key. The ++description is required to prevent all but the last key being discarded when ++the keys are linked into the keyring. + +This function is only available during initial kernel set up. diff --git a/include/keys/crypto-type.h b/include/keys/crypto-type.h -index 6b93366..710e77f 100644 +index 0fb362a..ed9b203 100644 --- a/include/keys/crypto-type.h +++ b/include/keys/crypto-type.h -@@ -31,4 +31,7 @@ extern void verify_sig_cancel(struct crypto_key_verify_context *ctx); +@@ -31,4 +31,7 @@ extern void verify_sig_cancel(struct crypto_sig_verify_context *ctx); * The payload is at the discretion of the subtype. */ +extern __init int preload_pgp_keys(const u8 *pgpdata, size_t pgpdatalen, -+ struct key *keyring, const char *descprefix); ++ struct key *keyring); + #endif /* _KEYS_CRYPTO_TYPE_H */ diff --git a/security/keys/crypto/Kconfig b/security/keys/crypto/Kconfig @@ -4175,10 +5420,10 @@ index a9a34c6..c873674 100644 pgp_key_parser-y := \ diff --git a/security/keys/crypto/pgp_preload.c b/security/keys/crypto/pgp_preload.c new file mode 100644 -index 0000000..9028788 +index 0000000..ca4cfe6 --- /dev/null +++ b/security/keys/crypto/pgp_preload.c -@@ -0,0 +1,96 @@ +@@ -0,0 +1,115 @@ +/* Cryptographic key request handling + * + * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. @@ -4202,32 +5447,23 @@ index 0000000..9028788 +struct preload_pgp_keys_context { + struct pgp_parse_context pgp; + key_ref_t keyring; -+ char descbuf[20]; -+ u8 key_n; -+ u8 dsize; ++ const u8 *key_start; ++ const u8 *key_end; ++ bool found_key; +}; + +/* -+ * Extract a public key or subkey from the PGP stream. ++ * Create a key. + */ -+static int __init found_pgp_key(struct pgp_parse_context *context, -+ enum pgp_packet_tag type, u8 headerlen, -+ const u8 *data, size_t datalen) ++static int __init create_pgp_key(struct preload_pgp_keys_context *ctx) +{ -+ struct preload_pgp_keys_context *ctx = -+ container_of(context, struct preload_pgp_keys_context, pgp); + key_ref_t key; + -+ if (ctx->key_n >= 255) -+ return 0; /* Don't overrun descbuf */ -+ -+ sprintf(ctx->descbuf + ctx->dsize, "%d", ctx->key_n++); -+ -+ key = key_create_or_update(ctx->keyring, "crypto", ctx->descbuf, -+ data - headerlen, datalen + headerlen, ++ key = key_create_or_update(ctx->keyring, "crypto", NULL, ++ ctx->key_start, ++ ctx->key_end - ctx->key_start, + KEY_POS_ALL | KEY_USR_VIEW, + KEY_ALLOC_NOT_IN_QUOTA); -+ + if (IS_ERR(key)) + return PTR_ERR(key); + @@ -4239,19 +5475,41 @@ index 0000000..9028788 + return 0; +} + ++/* ++ * Extract a public key or subkey from the PGP stream. ++ */ ++static int __init found_pgp_key(struct pgp_parse_context *context, ++ enum pgp_packet_tag type, u8 headerlen, ++ const u8 *data, size_t datalen) ++{ ++ struct preload_pgp_keys_context *ctx = ++ container_of(context, struct preload_pgp_keys_context, pgp); ++ int ret; ++ ++ if (ctx->found_key) { ++ ctx->key_end = data - headerlen; ++ ret = create_pgp_key(ctx); ++ if (ret < 0) ++ return ret; ++ } ++ ++ ctx->key_start = data - headerlen; ++ ctx->found_key = true; ++ return 0; ++} ++ +/** + * preload_pgp_keys - Load keys from a PGP keyring blob + * @pgpdata: The PGP keyring blob containing the keys. + * @pgpdatalen: The size of the @pgpdata blob. + * @keyring: The keyring to add the new keys to. -+ * @descprefix: The key description prefix. + * + * Preload a pack of keys from a PGP keyring blob. + * -+ * The keys are given description of @descprefix + the number of the key in the -+ * list. Since keys can be matched on their key IDs independently of the key -+ * description, the description is mostly irrelevant apart from the fact that -+ * keys of the same description displace one another from a keyring. ++ * The keys have their descriptions generated from the user ID and fingerprint ++ * in the PGP stream. Since keys can be matched on their key IDs independently ++ * of the key description, the description is mostly irrelevant apart from the ++ * fact that keys of the same description displace one another from a keyring. + * + * The caller should override the current creds if they want the keys to be + * owned by someone other than the current process's owner. Keys will not be @@ -4260,29 +5518,35 @@ index 0000000..9028788 + * This function may only be called whilst the kernel is booting. + */ +int __init preload_pgp_keys(const u8 *pgpdata, size_t pgpdatalen, -+ struct key *keyring, const char *descprefix) ++ struct key *keyring) +{ + struct preload_pgp_keys_context ctx; ++ int ret; + + ctx.pgp.types_of_interest = + (1 << PGP_PKT_PUBLIC_KEY) | (1 << PGP_PKT_PUBLIC_SUBKEY); + ctx.pgp.process_packet = found_pgp_key; + ctx.keyring = make_key_ref(keyring, 1); -+ ctx.key_n = 0; -+ ctx.dsize = strlen(descprefix); -+ BUG_ON(ctx.dsize > sizeof(ctx.descbuf) - 4); -+ strcpy(ctx.descbuf, descprefix); ++ ctx.found_key = false; + -+ return pgp_parse_packets(pgpdata, pgpdatalen, &ctx.pgp); ++ ret = pgp_parse_packets(pgpdata, pgpdatalen, &ctx.pgp); ++ if (ret < 0) ++ return ret; ++ ++ if (ctx.found_key) { ++ ctx.key_end = pgpdata + pgpdatalen; ++ return create_pgp_key(&ctx); ++ } ++ return 0; +} -- -1.7.11.2 +1.7.11.4 -From c9455441e0482bb5eb0ea8f1e2cfbe2e7d630560 Mon Sep 17 00:00:00 2001 +From d569964b0037289f291f5ac48df54a6b90b3435a Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:13:56 +0100 -Subject: [PATCH 15/28] Make most arch asm/module.h files use +Date: Thu, 16 Aug 2012 01:33:48 +0100 +Subject: [PATCH 17/32] Make most arch asm/module.h files use asm-generic/module.h Use the mapping of Elf_[SPE]hdr, Elf_Addr, Elf_Sym, Elf_Dyn, Elf_Rel/Rela, @@ -4319,7 +5583,10 @@ with a generic-y marker in the arch Kbuild file. Additionally, I have removed the bits from m32r and score that handle the unsupported type of relocation record as that's now handled centrally. +Thanks to Jonas Gorski for some MIPS fixes. + Signed-off-by: David Howells +Acked-by: Sam Ravnborg --- arch/Kconfig | 19 ++++++++++++++++++ arch/alpha/Kconfig | 2 ++ @@ -4346,7 +5613,7 @@ Signed-off-by: David Howells arch/m32r/include/asm/Kbuild | 2 ++ arch/m32r/include/asm/module.h | 10 ---------- arch/m32r/kernel/module.c | 15 -------------- - arch/m68k/Kconfig | 4 ++++ + arch/m68k/Kconfig | 3 +++ arch/m68k/include/asm/module.h | 6 ++---- arch/microblaze/Kconfig | 1 + arch/mips/Kconfig | 3 +++ @@ -4372,12 +5639,13 @@ Signed-off-by: David Howells arch/tile/Kconfig | 1 + arch/unicore32/Kconfig | 1 + arch/x86/Kconfig | 2 ++ + arch/x86/um/Kconfig | 2 ++ arch/xtensa/Kconfig | 1 + arch/xtensa/include/asm/module.h | 9 +-------- include/asm-generic/module.h | 40 +++++++++++++++++++++++++++++++------- include/linux/moduleloader.h | 36 ++++++++++++++++++++++++++++++---- kernel/module.c | 20 ------------------- - 56 files changed, 168 insertions(+), 223 deletions(-) + 57 files changed, 169 insertions(+), 223 deletions(-) delete mode 100644 arch/cris/include/asm/module.h delete mode 100644 arch/h8300/include/asm/module.h delete mode 100644 arch/m32r/include/asm/module.h @@ -4412,13 +5680,13 @@ index 72f2fa1..3450115 100644 + source "kernel/gcov/Kconfig" diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig -index d5b9b5e..e73a1a7 100644 +index 9944ded..7e3710c 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig -@@ -18,6 +18,8 @@ config ALPHA - select ARCH_HAVE_NMI_SAFE_CMPXCHG - select GENERIC_SMP_IDLE_THREAD +@@ -20,6 +20,8 @@ config ALPHA select GENERIC_CMOS_UPDATE + select GENERIC_STRNCPY_FROM_USER + select GENERIC_STRNLEN_USER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA help @@ -4451,7 +5719,7 @@ index 7b63743..9cd13b5 100644 #ifdef MODULE diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 7980873..f447a89 100644 +index e91c7cd..c75c217 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -50,6 +50,8 @@ config ARM @@ -4795,17 +6063,16 @@ index 3071fe8..38233b6 100644 - -} diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig -index 0b0f8b8..fcc5a65 100644 +index 4a46990..714a850 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig -@@ -12,6 +12,10 @@ config M68K +@@ -12,6 +12,9 @@ config M68K select FPU if MMU select ARCH_WANT_IPC_PARSE_VERSION select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_REL + select MODULES_USE_ELF_RELA -+ config RWSEM_GENERIC_SPINLOCK bool @@ -5262,7 +6529,7 @@ index b0a4743..5ef0814 100644 UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index ba2657c..afea8c7 100644 +index 8ec3a1a..01726cb 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -97,6 +97,8 @@ config X86 @@ -5274,6 +6541,22 @@ index ba2657c..afea8c7 100644 config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS || UPROBES) +diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig +index 9926e11..a4b0c10 100644 +--- a/arch/x86/um/Kconfig ++++ b/arch/x86/um/Kconfig +@@ -21,9 +21,11 @@ config 64BIT + config X86_32 + def_bool !64BIT + select HAVE_AOUT ++ select MODULES_USE_ELF_REL + + config X86_64 + def_bool 64BIT ++ select MODULES_USE_ELF_RELA + + config RWSEM_XCHGADD_ALGORITHM + def_bool X86_XADD && 64BIT diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 8ed64cf..4816e44 100644 --- a/arch/xtensa/Kconfig @@ -5453,13 +6736,408 @@ index 4edbd9c..087aeed 100644 { unsigned int i; -- -1.7.11.2 +1.7.11.4 -From 45c9f5b2992c100a9183f753d933d3141ae4e951 Mon Sep 17 00:00:00 2001 +From c6cfa3260f1e2961e69a2e3240695954aed24976 Mon Sep 17 00:00:00 2001 +From: Ralf Baechle +Date: Thu, 16 Aug 2012 01:38:43 +0100 +Subject: [PATCH 18/32] MIPS: Fix module.c build for 32 bit + +Fixes build failure introduced by "Make most arch asm/module.h files use +asm-generic/module.h" by moving all the RELA processing code to a +separate file to be used only for RELA processing on 64-bit kernels. + + CC arch/mips/kernel/module.o +arch/mips/kernel/module.c:250:14: error: 'reloc_handlers_rela' defined but not +used [-Werror=unused-variable] +cc1: all warnings being treated as errors + +make[6]: *** [arch/mips/kernel/module.o] Error 1 + +Signed-off-by: Ralf Baechle +Signed-off-by: David Howells +--- + arch/mips/kernel/Makefile | 1 + + arch/mips/kernel/module-rela.c | 144 +++++++++++++++++++++++++++++++++++++++++ + arch/mips/kernel/module.c | 124 +---------------------------------- + arch/mips/kernel/module.h | 12 ++++ + 4 files changed, 159 insertions(+), 122 deletions(-) + create mode 100644 arch/mips/kernel/module-rela.c + create mode 100644 arch/mips/kernel/module.h + +diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile +index fdaf65e..cd1e6c2 100644 +--- a/arch/mips/kernel/Makefile ++++ b/arch/mips/kernel/Makefile +@@ -31,6 +31,7 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o + + obj-$(CONFIG_STACKTRACE) += stacktrace.o + obj-$(CONFIG_MODULES) += mips_ksyms.o module.o ++obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o + + obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o + +diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c +new file mode 100644 +index 0000000..4e784a8 +--- /dev/null ++++ b/arch/mips/kernel/module-rela.c +@@ -0,0 +1,144 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Copyright (C) 2001 Rusty Russell. ++ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) ++ * Copyright (C) 2005 Thiemo Seufer ++ */ ++ ++#include ++#include ++#include ++#include ++#include "module.h" ++ ++static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) ++{ ++ *location = v; ++ ++ return 0; ++} ++ ++static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) ++{ ++ if (v % 4) { ++ pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", ++ me->name); ++ return -ENOEXEC; ++ } ++ ++ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { ++ printk(KERN_ERR ++ "module %s: relocation overflow\n", ++ me->name); ++ return -ENOEXEC; ++ } ++ ++ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); ++ ++ return 0; ++} ++ ++static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v) ++{ ++ *location = (*location & 0xffff0000) | ++ ((((long long) v + 0x8000LL) >> 16) & 0xffff); ++ ++ return 0; ++} ++ ++static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) ++{ ++ *location = (*location & 0xffff0000) | (v & 0xffff); ++ ++ return 0; ++} ++ ++static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) ++{ ++ *(Elf_Addr *)location = v; ++ ++ return 0; ++} ++ ++static int apply_r_mips_higher_rela(struct module *me, u32 *location, ++ Elf_Addr v) ++{ ++ *location = (*location & 0xffff0000) | ++ ((((long long) v + 0x80008000LL) >> 32) & 0xffff); ++ ++ return 0; ++} ++ ++static int apply_r_mips_highest_rela(struct module *me, u32 *location, ++ Elf_Addr v) ++{ ++ *location = (*location & 0xffff0000) | ++ ((((long long) v + 0x800080008000LL) >> 48) & 0xffff); ++ ++ return 0; ++} ++ ++static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, ++ Elf_Addr v) = { ++ [R_MIPS_NONE] = apply_r_mips_none, ++ [R_MIPS_32] = apply_r_mips_32_rela, ++ [R_MIPS_26] = apply_r_mips_26_rela, ++ [R_MIPS_HI16] = apply_r_mips_hi16_rela, ++ [R_MIPS_LO16] = apply_r_mips_lo16_rela, ++ [R_MIPS_64] = apply_r_mips_64_rela, ++ [R_MIPS_HIGHER] = apply_r_mips_higher_rela, ++ [R_MIPS_HIGHEST] = apply_r_mips_highest_rela ++}; ++ ++int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, ++ unsigned int symindex, unsigned int relsec, ++ struct module *me) ++{ ++ Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; ++ Elf_Sym *sym; ++ u32 *location; ++ unsigned int i; ++ Elf_Addr v; ++ int res; ++ ++ pr_debug("Applying relocate section %u to %u\n", relsec, ++ sechdrs[relsec].sh_info); ++ ++ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { ++ /* This is where to make the change */ ++ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr ++ + rel[i].r_offset; ++ /* This is the symbol it is referring to */ ++ sym = (Elf_Sym *)sechdrs[symindex].sh_addr ++ + ELF_MIPS_R_SYM(rel[i]); ++ if (IS_ERR_VALUE(sym->st_value)) { ++ /* Ignore unresolved weak symbol */ ++ if (ELF_ST_BIND(sym->st_info) == STB_WEAK) ++ continue; ++ printk(KERN_WARNING "%s: Unknown symbol %s\n", ++ me->name, strtab + sym->st_name); ++ return -ENOENT; ++ } ++ ++ v = sym->st_value + rel[i].r_addend; ++ ++ res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); ++ if (res) ++ return res; ++ } ++ ++ return 0; ++} +diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c +index 1500c80..74a7197 100644 +--- a/arch/mips/kernel/module.c ++++ b/arch/mips/kernel/module.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include "module.h" + + #include /* MODULE_START */ + +@@ -53,7 +54,7 @@ void *module_alloc(unsigned long size) + } + #endif + +-static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) ++int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) + { + return 0; + } +@@ -65,13 +66,6 @@ static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v) + return 0; + } + +-static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) +-{ +- *location = v; +- +- return 0; +-} +- + static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) + { + if (v % 4) { +@@ -93,26 +87,6 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) + return 0; + } + +-static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) +-{ +- if (v % 4) { +- pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", +- me->name); +- return -ENOEXEC; +- } +- +- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { +- printk(KERN_ERR +- "module %s: relocation overflow\n", +- me->name); +- return -ENOEXEC; +- } +- +- *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); +- +- return 0; +-} +- + static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) + { + struct mips_hi16 *n; +@@ -134,14 +108,6 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) + return 0; + } + +-static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v) +-{ +- *location = (*location & 0xffff0000) | +- ((((long long) v + 0x8000LL) >> 16) & 0xffff); +- +- return 0; +-} +- + static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) + { + unsigned long insnlo = *location; +@@ -206,38 +172,6 @@ out_danger: + return -ENOEXEC; + } + +-static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) +-{ +- *location = (*location & 0xffff0000) | (v & 0xffff); +- +- return 0; +-} +- +-static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) +-{ +- *(Elf_Addr *)location = v; +- +- return 0; +-} +- +-static int apply_r_mips_higher_rela(struct module *me, u32 *location, +- Elf_Addr v) +-{ +- *location = (*location & 0xffff0000) | +- ((((long long) v + 0x80008000LL) >> 32) & 0xffff); +- +- return 0; +-} +- +-static int apply_r_mips_highest_rela(struct module *me, u32 *location, +- Elf_Addr v) +-{ +- *location = (*location & 0xffff0000) | +- ((((long long) v + 0x800080008000LL) >> 48) & 0xffff); +- +- return 0; +-} +- + static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, + Elf_Addr v) = { + [R_MIPS_NONE] = apply_r_mips_none, +@@ -247,18 +181,6 @@ static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, + [R_MIPS_LO16] = apply_r_mips_lo16_rel + }; + +-static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, +- Elf_Addr v) = { +- [R_MIPS_NONE] = apply_r_mips_none, +- [R_MIPS_32] = apply_r_mips_32_rela, +- [R_MIPS_26] = apply_r_mips_26_rela, +- [R_MIPS_HI16] = apply_r_mips_hi16_rela, +- [R_MIPS_LO16] = apply_r_mips_lo16_rela, +- [R_MIPS_64] = apply_r_mips_64_rela, +- [R_MIPS_HIGHER] = apply_r_mips_higher_rela, +- [R_MIPS_HIGHEST] = apply_r_mips_highest_rela +-}; +- + int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, + struct module *me) +@@ -299,48 +221,6 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, + return 0; + } + +-#ifdef CONFIG_MODULES_USE_ELF_RELA +-int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, +- unsigned int symindex, unsigned int relsec, +- struct module *me) +-{ +- Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; +- Elf_Sym *sym; +- u32 *location; +- unsigned int i; +- Elf_Addr v; +- int res; +- +- pr_debug("Applying relocate section %u to %u\n", relsec, +- sechdrs[relsec].sh_info); +- +- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { +- /* This is where to make the change */ +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +- + rel[i].r_offset; +- /* This is the symbol it is referring to */ +- sym = (Elf_Sym *)sechdrs[symindex].sh_addr +- + ELF_MIPS_R_SYM(rel[i]); +- if (IS_ERR_VALUE(sym->st_value)) { +- /* Ignore unresolved weak symbol */ +- if (ELF_ST_BIND(sym->st_info) == STB_WEAK) +- continue; +- printk(KERN_WARNING "%s: Unknown symbol %s\n", +- me->name, strtab + sym->st_name); +- return -ENOENT; +- } +- +- v = sym->st_value + rel[i].r_addend; +- +- res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); +- if (res) +- return res; +- } +- +- return 0; +-} +-#endif +- + /* Given an address, look for it in the module exception tables. */ + const struct exception_table_entry *search_module_dbetables(unsigned long addr) + { +diff --git a/arch/mips/kernel/module.h b/arch/mips/kernel/module.h +new file mode 100644 +index 0000000..675d091 +--- /dev/null ++++ b/arch/mips/kernel/module.h +@@ -0,0 +1,12 @@ ++/* Internal definitions for MIPS module code ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++/* ++ * module.c ++ */ ++extern int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v); +-- +1.7.11.4 + + +From 661f0147e9414fb2237f56d88d1f92d8a42345c9 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:13:57 +0100 -Subject: [PATCH 16/28] Provide macros for forming the name of an ELF note and +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 19/32] Provide macros for forming the name of an ELF note and its section Provide macros for stringifying the name of an ELF note and its section @@ -5493,13 +7171,13 @@ index 278e3ef..949d494 100644 #endif /* _LINUX_ELFNOTE_H */ -- -1.7.11.2 +1.7.11.4 -From 1d83fa4cf20b3b6f7ffd471459dcad47d6e2ac64 Mon Sep 17 00:00:00 2001 +From 544f02e192a8a38153d7dedc61bc107545666c0d Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:00 +0100 -Subject: [PATCH 17/28] MODSIGN: Provide gitignore and make clean rules for +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 20/32] MODSIGN: Provide gitignore and make clean rules for extra files Provide gitignore and make clean rules for extra files to hide and clean up the @@ -5542,7 +7220,7 @@ index 57af07c..7948eeb 100644 +random_seed +trustdb.gpg diff --git a/Makefile b/Makefile -index 8e4c0a7..4db9629 100644 +index ddf5be9..70a6b5b 100644 --- a/Makefile +++ b/Makefile @@ -1239,6 +1239,7 @@ clean: $(clean-dirs) @@ -5564,13 +7242,13 @@ index e9b7abe..223dfd6 100644 +mod-extract -- -1.7.11.2 +1.7.11.4 -From a284aee7526543a96a6e5694425ec7a2001d5c32 Mon Sep 17 00:00:00 2001 +From 6e21809168e7b45a830ec354ec9fc1582fcffe4f Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:01 +0100 -Subject: [PATCH 18/28] MODSIGN: Provide Documentation and Kconfig options +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 21/32] MODSIGN: Provide Documentation and Kconfig options Provide documentation and kernel configuration options for module signing. @@ -5909,13 +7587,13 @@ index af6c7f8..e23ed83 100644 config INIT_ALL_POSSIBLE -- -1.7.11.2 +1.7.11.4 -From 509093b115e362fd50584c5852c922926c2395bd Mon Sep 17 00:00:00 2001 +From 7733934d34b7f03574b4578edfad4a60d6fe3d56 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:01 +0100 -Subject: [PATCH 19/28] MODSIGN: Sign modules during the build process +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 22/32] MODSIGN: Sign modules during the build process If CONFIG_MODULE_SIG is set, then this patch will cause the module to get a signature installed. The following steps will occur: @@ -7034,13 +8712,13 @@ index 0000000..bca67c0 + +exit 0 -- -1.7.11.2 +1.7.11.4 -From 6a2e8f0245dadda42c355eda278110f496e3a6d5 Mon Sep 17 00:00:00 2001 +From ee3ca99bcf972f0d072d91f9256c39a197153b8e Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:01 +0100 -Subject: [PATCH 20/28] MODSIGN: Module signature verification stub +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 23/32] MODSIGN: Module signature verification stub Create a stub for the module signature verifier and link it into module.c so that it gets called. A field is added to struct module to record whether or @@ -7422,13 +9100,13 @@ index 087aeed..a59a9da 100644 if (last_unloaded_module[0]) printk(" [last unloaded: %s]", last_unloaded_module); -- -1.7.11.2 +1.7.11.4 -From 62c90369e58486688303c4803e39d7df44a932f9 Mon Sep 17 00:00:00 2001 +From 0f8f372047d8220e1d918797972746bb9fe345d9 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:02 +0100 -Subject: [PATCH 21/28] MODSIGN: Automatically generate module signing keys if +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 24/32] MODSIGN: Automatically generate module signing keys if missing Automatically generate keys for module signing if they're absent so that @@ -7504,13 +9182,13 @@ index cec222a..28cd248 100644 +endif +CLEAN_FILES += modsign.pub modsign.sec genkey random_seed -- -1.7.11.2 +1.7.11.4 -From 00ce30147994ed4a503bdb051350a4601c565dcc Mon Sep 17 00:00:00 2001 +From be5544dce081ccb49fd452a6273c5024208b2f06 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:02 +0100 -Subject: [PATCH 22/28] MODSIGN: Provide module signing public keys to the +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 25/32] MODSIGN: Provide module signing public keys to the kernel Include a PGP keyring containing the public keys required to perform module @@ -7582,7 +9260,7 @@ index 28cd248..1d20704 100644 echo "%no-protection: yes" >> genkey diff --git a/kernel/modsign-pubkey.c b/kernel/modsign-pubkey.c new file mode 100644 -index 0000000..17e02f5 +index 0000000..5fdb082 --- /dev/null +++ b/kernel/modsign-pubkey.c @@ -0,0 +1,75 @@ @@ -7655,7 +9333,7 @@ index 0000000..17e02f5 + + if (preload_pgp_keys(modsign_public_keys, + modsign_public_keys_end - modsign_public_keys, -+ modsign_keyring, "modsign.") < 0) ++ modsign_keyring) < 0) + panic("Can't load module signing keys\n"); + + return 0; @@ -7690,13 +9368,13 @@ index 4bf857e..05473e6 100644 #include #include -- -1.7.11.2 +1.7.11.4 -From 9b94f77eea94d028df6a041e6772f9f142eb89e7 Mon Sep 17 00:00:00 2001 +From 34c918aacc002f8a7226a26a0d8af614c6f4430e Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:02 +0100 -Subject: [PATCH 23/28] MODSIGN: Check the ELF container +Date: Thu, 16 Aug 2012 01:38:45 +0100 +Subject: [PATCH 26/32] MODSIGN: Check the ELF container Check the ELF container of the kernel module to prevent the kernel from crashing or getting corrupted whilst trying to use it and locate the module @@ -8026,13 +9704,13 @@ index 05473e6..2161d11 100644 /* Deal with an unsigned module */ if (modsign_signedonly) { -- -1.7.11.2 +1.7.11.4 -From 60ca7dc263084abcf68325ed86d2765148f60225 Mon Sep 17 00:00:00 2001 +From 2de4559e24c416e6813c10edbe3cc433ecd0dd50 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:02 +0100 -Subject: [PATCH 24/28] MODSIGN: Produce a filtered and canonicalised section +Date: Thu, 16 Aug 2012 01:38:46 +0100 +Subject: [PATCH 27/32] MODSIGN: Produce a filtered and canonicalised section list Build a list of the sections in which we're interested and canonicalise the @@ -8150,13 +9828,13 @@ index 2161d11..646b104 100644 out: switch (ret) { -- -1.7.11.2 +1.7.11.4 -From b847c539c4fb7d71ab7383e79b3e6c0683a23a7e Mon Sep 17 00:00:00 2001 +From 3c8e71a46663f1fc3ee49fe3f6fa5c3bb85b704c Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:03 +0100 -Subject: [PATCH 25/28] MODSIGN: Create digest of module content and check +Date: Thu, 16 Aug 2012 01:38:46 +0100 +Subject: [PATCH 28/32] MODSIGN: Create digest of module content and check signature Apply signature checking to modules on module load, checking the signature @@ -8199,14 +9877,23 @@ somewhat smaller code. Signed-off-by: David Howells --- - kernel/module-verify-defs.h | 11 +- + kernel/module-verify-defs.h | 13 +- kernel/module-verify.c | 332 +++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 337 insertions(+), 6 deletions(-) + 2 files changed, 338 insertions(+), 7 deletions(-) diff --git a/kernel/module-verify-defs.h b/kernel/module-verify-defs.h -index 2fe31e1..82952b0 100644 +index 2fe31e1..cb477a2 100644 --- a/kernel/module-verify-defs.h +++ b/kernel/module-verify-defs.h +@@ -19,7 +19,7 @@ extern struct key *modsign_keyring; + * Internal state + */ + struct module_verify_data { +- struct crypto_key_verify_context *mod_sig; /* Module signing context */ ++ struct crypto_sig_verify_context *mod_sig; /* Module signing context */ + union { + const void *buffer; /* module buffer */ + const Elf_Ehdr *hdr; /* ELF header */ @@ -42,15 +42,16 @@ struct module_verify_data { /* * Whether or not we support various types of ELF relocation record @@ -8230,7 +9917,7 @@ index 2fe31e1..82952b0 100644 /* diff --git a/kernel/module-verify.c b/kernel/module-verify.c -index 646b104..e275759 100644 +index 646b104..bee7e04 100644 --- a/kernel/module-verify.c +++ b/kernel/module-verify.c @@ -50,6 +50,22 @@ static bool modsign_signedonly; @@ -8456,7 +10143,7 @@ index 646b104..e275759 100644 + */ +static noinline int module_verify_signature(struct module_verify_data *mvdata) +{ -+ struct crypto_key_verify_context *mod_sig; ++ struct crypto_sig_verify_context *mod_sig; + const Elf_Shdr *sechdrs = mvdata->sections; + const char *secstrings = mvdata->secstrings; + const u8 *sig = mvdata->sig; @@ -8587,13 +10274,13 @@ index 646b104..e275759 100644 out: -- -1.7.11.2 +1.7.11.4 -From 86969bc531b37c88b499311abae41e0116666dcc Mon Sep 17 00:00:00 2001 +From 53142a9c74e2922885d03555d26213fc38553b90 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:03 +0100 -Subject: [PATCH 26/28] MODSIGN: Suppress some redundant ELF checks +Date: Thu, 16 Aug 2012 01:38:46 +0100 +Subject: [PATCH 29/32] MODSIGN: Suppress some redundant ELF checks Suppress some redundant ELF checks in module_verify_elf() that are also done by copy_and_check() in the core module loader code prior to calling @@ -8605,7 +10292,7 @@ Signed-off-by: David Howells 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/module-verify.c b/kernel/module-verify.c -index e275759..bfd1286 100644 +index bee7e04..f3a694f 100644 --- a/kernel/module-verify.c +++ b/kernel/module-verify.c @@ -97,11 +97,11 @@ do { if (unlikely(!(X))) { line = __LINE__; goto symcheck_error; } } while (0) @@ -8624,13 +10311,13 @@ index e275759..bfd1286 100644 /* Validate the section table contents */ mvdata->nsects = hdr->e_shnum; -- -1.7.11.2 +1.7.11.4 -From 4d5a1f0360ce04a24b847eee2da84d9618375ce8 Mon Sep 17 00:00:00 2001 +From 14d36171021b1c16f6c664bd4ab31e1d989ab282 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Tue, 24 Jul 2012 14:14:03 +0100 -Subject: [PATCH 27/28] MODSIGN: Panic the kernel if FIPS is enabled upon +Date: Thu, 16 Aug 2012 01:38:46 +0100 +Subject: [PATCH 30/32] MODSIGN: Panic the kernel if FIPS is enabled upon module signing failure If module signing fails when the kernel is running with FIPS enabled then the @@ -8644,7 +10331,7 @@ Signed-off-by: David Howells 1 file changed, 5 insertions(+) diff --git a/kernel/module-verify.c b/kernel/module-verify.c -index bfd1286..b9c3955 100644 +index f3a694f..896c0ff 100644 --- a/kernel/module-verify.c +++ b/kernel/module-verify.c @@ -30,6 +30,7 @@ @@ -8667,13 +10354,13 @@ index bfd1286..b9c3955 100644 case 0: /* Good signature */ *_gpgsig_ok = true; -- -1.7.11.2 +1.7.11.4 -From dd6e65be6a8f225018259b16161decc26c09c300 Mon Sep 17 00:00:00 2001 +From 1e8e625508f013acfb8ade3b5c30dcc7ff710ce9 Mon Sep 17 00:00:00 2001 From: Josh Boyer -Date: Thu, 2 Aug 2012 14:35:44 +0100 -Subject: [PATCH 28/28] MODSIGN: Allow modules to be signed with an unknown +Date: Thu, 16 Aug 2012 01:38:46 +0100 +Subject: [PATCH 31/32] MODSIGN: Allow modules to be signed with an unknown key unless enforcing Currently we fail the loading of modules that are signed with a public key @@ -8691,7 +10378,7 @@ Signed-off-by: David Howells 1 file changed, 7 insertions(+) diff --git a/kernel/module-verify.c b/kernel/module-verify.c -index b9c3955..22036d4 100644 +index 896c0ff..041506f 100644 --- a/kernel/module-verify.c +++ b/kernel/module-verify.c @@ -736,6 +736,13 @@ out: @@ -8709,13 +10396,14 @@ index b9c3955..22036d4 100644 default: /* Other error (probably ENOMEM) */ break; -- -1.7.11.2 +1.7.11.4 -From bccd1bfe487e1f4df543f7a160cc9876d7d96fb7 Mon Sep 17 00:00:00 2001 + +From 7ac7095ee6624789c6a971d16f5ca823ebbde3c7 Mon Sep 17 00:00:00 2001 From: Peter Jones -Date: Thu, 2 Aug 2012 23:09:19 +0100 -Subject: [PATCH] MODSIGN: Fix documentation of signed-nokey behavior when not - enforcing. +Date: Thu, 16 Aug 2012 01:38:46 +0100 +Subject: [PATCH 32/32] MODSIGN: Fix documentation of signed-nokey behavior + when not enforcing. jwboyer's previous commit changes the behavior of module signing when there's a valid signature but we don't know the public key and are in @@ -8742,5 +10430,5 @@ index d75d473..8c4bef9 100644 Invalidly signed, public key EKEYREJECTED EKEYREJECTED Validly signed, expired key EKEYEXPIRED EKEYEXPIRED -- -1.7.11.2 +1.7.11.4 diff --git a/sources b/sources index 80d0bc7fe..568d4bd26 100644 --- a/sources +++ b/sources @@ -1,2 +1,3 @@ 24153eaaa81dedc9481ada8cd9c3b83d linux-3.5.tar.xz 5f0ec612b5364c18386c1b8155c271ac patch-3.6-rc2.xz +12edd20554fd9469c5d7fad9935ce0af patch-3.6-rc2-git1.xz diff --git a/vfs-fix-file-creation-bugs.patch b/vfs-fix-file-creation-bugs.patch deleted file mode 100644 index b4e621645..000000000 --- a/vfs-fix-file-creation-bugs.patch +++ /dev/null @@ -1,393 +0,0 @@ -Path: news.gmane.org!not-for-mail -From: Miklos Szeredi -Newsgroups: gmane.linux.kernel,gmane.linux.file-systems,gmane.linux.kernel.stable -Subject: [PATCH 1/4] vfs: canonicalize create mode in build_open_flags() -Date: Tue, 7 Aug 2012 14:45:46 +0200 -Lines: 37 -Approved: news@gmane.org -Message-ID: <1344343549-11887-2-git-send-email-miklos@szeredi.hu> -References: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -NNTP-Posting-Host: plane.gmane.org -X-Trace: dough.gmane.org 1344343547 29032 80.91.229.3 (7 Aug 2012 12:45:47 GMT) -X-Complaints-To: usenet@dough.gmane.org -NNTP-Posting-Date: Tue, 7 Aug 2012 12:45:47 +0000 (UTC) -Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, - rjones@redhat.com, steveamigauk@yahoo.co.uk, mszeredi@suse.cz, - stable@vger.kernel.org -To: viro@ZenIV.linux.org.uk -Original-X-From: linux-kernel-owner@vger.kernel.org Tue Aug 07 14:45:47 2012 -Return-path: -Envelope-to: glk-linux-kernel-3@plane.gmane.org -Original-Received: from vger.kernel.org ([209.132.180.67]) - by plane.gmane.org with esmtp (Exim 4.69) - (envelope-from ) - id 1SyjAQ-0007sm-7c - for glk-linux-kernel-3@plane.gmane.org; Tue, 07 Aug 2012 14:45:46 +0200 -Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S1754555Ab2HGMpi (ORCPT ); - Tue, 7 Aug 2012 08:45:38 -0400 -Original-Received: from mail-we0-f174.google.com ([74.125.82.174]:58092 "EHLO - mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S1754305Ab2HGMoe (ORCPT - ); - Tue, 7 Aug 2012 08:44:34 -0400 -Original-Received: by weyx8 with SMTP id x8so2645788wey.19 - for ; Tue, 07 Aug 2012 05:44:32 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=szeredi.hu; s=google; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; - bh=1qjbKUe4PMMa48XDr0iiAZbSQDjKIFlASvIcoWSByLY=; - b=Btq8S/0RNrAMDqIuqkWxTXUBX1CBdRNl9d47rqc2ZXzMxnyHfqOTM+/GYZBQkM5Fm7 - W11AcmLVTWQ6e6Av98QIpw4aiC35KI1NQwyEGs3+QmzJE+nO706XT4QK+TW7ynd6Rssq - UC+GVbxB6Ix7QdVmtgZO6EfXEJ4sxLMqeatuc= -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20120113; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references - :x-gm-message-state; - bh=1qjbKUe4PMMa48XDr0iiAZbSQDjKIFlASvIcoWSByLY=; - b=LNbJeP9fTZ3nOJiZO4BWNTuTQ5G5tmcNb1TwWGPxerdYqKYQTyEop2fUJPOQBftC5R - t34Oi+kpvLRUhjyAAkTefiqaNupAQVXdg2kV2PgRYWDjFR9acKHnmzhbEsozi98G+Xp/ - UsERBlNsx3CYLBhuuWK70HIZ8Zp1Pg8YzhhmXO2sW4bGDRa8/ZCeTTmJ5owb7zuZugAT - I+blTuEakAco+9SubhMh9XR0T3us/2LcUxv0KIA0GK/CzBlig5iBTFH1IU9EhS6ZkBpL - rRsM1o14L6POmPxH9J5GolEUjCBfBet54Y0pPp8hytWrOGCz7cbejS++c4/Lu8mOvQfS - FgXw== -Original-Received: by 10.216.54.146 with SMTP id i18mr7274525wec.187.1344343472653; - Tue, 07 Aug 2012 05:44:32 -0700 (PDT) -Original-Received: from localhost.localdomain (77-234-87-236.pool.digikabel.hu. [77.234.87.236]) - by mx.google.com with ESMTPS id b7sm31225742wiz.9.2012.08.07.05.44.30 - (version=TLSv1/SSLv3 cipher=OTHER); - Tue, 07 Aug 2012 05:44:31 -0700 (PDT) -X-Mailer: git-send-email 1.7.7 -In-Reply-To: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -X-Gm-Message-State: ALoCoQlBs8Zo4YKrYg/AUMfG82CQVVCikUAknZuRKPe9oykBM4fMvZfn22FIif3NtkSoDwAQss82 -Original-Sender: linux-kernel-owner@vger.kernel.org -Precedence: bulk -List-ID: -X-Mailing-List: linux-kernel@vger.kernel.org -Xref: news.gmane.org gmane.linux.kernel:1339000 gmane.linux.file-systems:66449 gmane.linux.kernel.stable:29234 -Archived-At: - -From: Miklos Szeredi - -Userspace can pass weird create mode in open(2) that we canonicalize to -"(mode & S_IALLUGO) | S_IFREG" in vfs_create(). - -The problem is that we use the uncanonicalized mode before calling vfs_create() -with unforseen consequences. - -So do the canonicalization early in build_open_flags(). - -Signed-off-by: Miklos Szeredi -CC: stable@vger.kernel.org ---- - fs/open.c | 7 ++++--- - 1 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/fs/open.c b/fs/open.c -index bc132e1..e1f2cdb 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o - int lookup_flags = 0; - int acc_mode; - -- if (!(flags & O_CREAT)) -- mode = 0; -- op->mode = mode; -+ if (flags & O_CREAT) -+ op->mode = (mode & S_IALLUGO) | S_IFREG; -+ else -+ op->mode = 0; - - /* Must never be set by userspace */ - flags &= ~FMODE_NONOTIFY; --- -1.7.7 - -Path: news.gmane.org!not-for-mail -From: Miklos Szeredi -Newsgroups: gmane.linux.kernel,gmane.linux.file-systems -Subject: [PATCH 2/4] vfs: atomic_open(): fix create mode usage -Date: Tue, 7 Aug 2012 14:45:47 +0200 -Lines: 29 -Approved: news@gmane.org -Message-ID: <1344343549-11887-3-git-send-email-miklos@szeredi.hu> -References: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -NNTP-Posting-Host: plane.gmane.org -X-Trace: dough.gmane.org 1344343484 28394 80.91.229.3 (7 Aug 2012 12:44:44 GMT) -X-Complaints-To: usenet@dough.gmane.org -NNTP-Posting-Date: Tue, 7 Aug 2012 12:44:44 +0000 (UTC) -Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, - rjones@redhat.com, steveamigauk@yahoo.co.uk, mszeredi@suse.cz -To: viro@ZenIV.linux.org.uk -Original-X-From: linux-kernel-owner@vger.kernel.org Tue Aug 07 14:44:43 2012 -Return-path: -Envelope-to: glk-linux-kernel-3@plane.gmane.org -Original-Received: from vger.kernel.org ([209.132.180.67]) - by plane.gmane.org with esmtp (Exim 4.69) - (envelope-from ) - id 1Syj9O-0006lB-Q1 - for glk-linux-kernel-3@plane.gmane.org; Tue, 07 Aug 2012 14:44:43 +0200 -Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S1754569Ab2HGMoi (ORCPT ); - Tue, 7 Aug 2012 08:44:38 -0400 -Original-Received: from mail-we0-f174.google.com ([74.125.82.174]:42649 "EHLO - mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S1754511Ab2HGMof (ORCPT - ); - Tue, 7 Aug 2012 08:44:35 -0400 -Original-Received: by mail-we0-f174.google.com with SMTP id x8so2645765wey.19 - for ; Tue, 07 Aug 2012 05:44:34 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=szeredi.hu; s=google; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; - bh=AdrwH4TefuleTVZB4XFHvywWtuGocoaapFFX4/PnPN0=; - b=ZSz4WBTINxIVhKr/eL2BAQWxfdNF5XH0PEKbSlALRQbOHT4yZ8w+3/NNDp8DjUhydl - vQQijSva0g32a2N3dORJtNjcoplZyqzo4SKSTBFbaUfXvlHIxJaOq0KcDSS5huMe/yk8 - XU1djDAt7kma9A3oTQh59ASLumUpCeVqOue6g= -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20120113; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references - :x-gm-message-state; - bh=AdrwH4TefuleTVZB4XFHvywWtuGocoaapFFX4/PnPN0=; - b=Js4PjFw+6ckXxUvsGO/Sz2QTTxEdZsRF4SvTScOgL6ugRFWnK+U/4t1c+rRfHkfDfD - i5G2afUaZB0JRnPIxmpSkly92cu/sI+fdeFDpuls3m5GPQ4CMmXHbl1Ev42BTqTB6y1G - UsXYw14QYf+XbnrJgJ1MKMX+hJlBMfyu8A3kh54RtJsBYBYd4u7vWnDKRhCGudhj9XGY - s19MCkfJDyhWl7k84NjzlLUEN1LLwFF+ZDd086+95BrtlO7ta35r7WjTrj7eIz/JQ2wf - RBmbh2SHh1BplRm20j0YRNvWvrUUn0CDwCOx2PpN+zQsMRmYwAMh/cfJHbrf6sEtWmDU - HPuQ== -Original-Received: by 10.180.83.106 with SMTP id p10mr27242596wiy.21.1344343474226; - Tue, 07 Aug 2012 05:44:34 -0700 (PDT) -Original-Received: from localhost.localdomain (77-234-87-236.pool.digikabel.hu. [77.234.87.236]) - by mx.google.com with ESMTPS id b7sm31225742wiz.9.2012.08.07.05.44.32 - (version=TLSv1/SSLv3 cipher=OTHER); - Tue, 07 Aug 2012 05:44:33 -0700 (PDT) -X-Mailer: git-send-email 1.7.7 -In-Reply-To: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -X-Gm-Message-State: ALoCoQn5VhymZvNT7mcpKezP10+ERZVrDOUy6d1v5xWL8OcMf7YtYh9K43mLEBvJE7elSPegM6gs -Original-Sender: linux-kernel-owner@vger.kernel.org -Precedence: bulk -List-ID: -X-Mailing-List: linux-kernel@vger.kernel.org -Xref: news.gmane.org gmane.linux.kernel:1338997 gmane.linux.file-systems:66446 -Archived-At: - -From: Miklos Szeredi - -Don't mask S_ISREG off the create mode before passing to ->atomic_open(). Other -methods (->create, ->mknod) also get the complete file mode and filesystems -expect it. - -Reported-by: Steve -Reported-by: Richard W.M. Jones -Signed-off-by: Miklos Szeredi ---- - fs/namei.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/fs/namei.c b/fs/namei.c -index 1b46439..5bac1bb 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, - goto out; - } - -- mode = op->mode & S_IALLUGO; -+ mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) - mode &= ~current_umask(); - --- -1.7.7 - -Path: news.gmane.org!not-for-mail -From: Miklos Szeredi -Newsgroups: gmane.linux.kernel,gmane.linux.file-systems -Subject: [PATCH 3/4] vfs: pass right create mode to may_o_create() -Date: Tue, 7 Aug 2012 14:45:48 +0200 -Lines: 25 -Approved: news@gmane.org -Message-ID: <1344343549-11887-4-git-send-email-miklos@szeredi.hu> -References: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -NNTP-Posting-Host: plane.gmane.org -X-Trace: dough.gmane.org 1344343526 28841 80.91.229.3 (7 Aug 2012 12:45:26 GMT) -X-Complaints-To: usenet@dough.gmane.org -NNTP-Posting-Date: Tue, 7 Aug 2012 12:45:26 +0000 (UTC) -Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, - rjones@redhat.com, steveamigauk@yahoo.co.uk, mszeredi@suse.cz -To: viro@ZenIV.linux.org.uk -Original-X-From: linux-kernel-owner@vger.kernel.org Tue Aug 07 14:45:24 2012 -Return-path: -Envelope-to: glk-linux-kernel-3@plane.gmane.org -Original-Received: from vger.kernel.org ([209.132.180.67]) - by plane.gmane.org with esmtp (Exim 4.69) - (envelope-from ) - id 1Syj9z-0007QH-Q3 - for glk-linux-kernel-3@plane.gmane.org; Tue, 07 Aug 2012 14:45:20 +0200 -Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S1754608Ab2HGMpK (ORCPT ); - Tue, 7 Aug 2012 08:45:10 -0400 -Original-Received: from mail-we0-f174.google.com ([74.125.82.174]:58092 "EHLO - mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S1754059Ab2HGMog (ORCPT - ); - Tue, 7 Aug 2012 08:44:36 -0400 -Original-Received: by mail-we0-f174.google.com with SMTP id x8so2645788wey.19 - for ; Tue, 07 Aug 2012 05:44:35 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=szeredi.hu; s=google; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; - bh=nl2pPzHwW8KM+I7iQTOh9PYtYJohI6BIhk/K8K5LBQo=; - b=LseVfH0Fqa0ZLiIt9+N/ozV8rHtd85QSg6ixoDjgzR5Mh28J5FMzUVGjcnJzGDrMqJ - iTGbA8CSMcE2WykswC+5rJUKFxPw9u7mjaPutqcV8aAc6Ii2i1D7oIUO7O6qhyiiPWnZ - 2fFGR2LPOOrPF/tzVZX/9Rcwc6nNJLdlr6PU0= -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20120113; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references - :x-gm-message-state; - bh=nl2pPzHwW8KM+I7iQTOh9PYtYJohI6BIhk/K8K5LBQo=; - b=MkUpj/XL8pOrHQYqjessDHSpc3Cn3OK8rTtvlzSLRA7ktxqXk1w4mVGrI3SVSrat+V - eu5OziG+pXw/+SVENp5VBksJuvbeq791pBjXINPJLh/Wv4c3kRCHyymT5lIDam24tBJQ - xgvurY4/P9r5vfxHQiG6/SOltCvldN+QyHeXDfEwlvxr4GDovGJ0VvUp3t70oCPh6TnQ - w8XhnTrnaa02wThfpz7RYtCIxyDMAnZTX6vxKlzURVxcdmVjMu4kPA8CMWgizOi/S9l0 - 6ZDGhqqY0jdtbdncf6MkL25vulJvCF5Uf4WfyR8+REGS5f8V8sMWFFurp1S2LYEdLJ5o - 7WtQ== -Original-Received: by 10.180.20.11 with SMTP id j11mr27275578wie.12.1344343475796; - Tue, 07 Aug 2012 05:44:35 -0700 (PDT) -Original-Received: from localhost.localdomain (77-234-87-236.pool.digikabel.hu. [77.234.87.236]) - by mx.google.com with ESMTPS id b7sm31225742wiz.9.2012.08.07.05.44.34 - (version=TLSv1/SSLv3 cipher=OTHER); - Tue, 07 Aug 2012 05:44:35 -0700 (PDT) -X-Mailer: git-send-email 1.7.7 -In-Reply-To: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -X-Gm-Message-State: ALoCoQkO1sLF/IsgU7JMCP9gmfCSYZh8gUPun3lkVeiAXebgfb+UIaib3NfgHI+ihXW0gPxiVeOq -Original-Sender: linux-kernel-owner@vger.kernel.org -Precedence: bulk -List-ID: -X-Mailing-List: linux-kernel@vger.kernel.org -Xref: news.gmane.org gmane.linux.kernel:1338999 gmane.linux.file-systems:66448 -Archived-At: - -From: Miklos Szeredi - -Pass the umask-ed create mode to may_o_create() instead of the original one. - -Signed-off-by: Miklos Szeredi ---- - fs/namei.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/fs/namei.c b/fs/namei.c -index 5bac1bb..26c28ec 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, - } - - if (open_flag & O_CREAT) { -- error = may_o_create(&nd->path, dentry, op->mode); -+ error = may_o_create(&nd->path, dentry, mode); - if (error) { - create_error = error; - if (open_flag & O_EXCL) --- -1.7.7 - -Path: news.gmane.org!not-for-mail -From: Miklos Szeredi -Newsgroups: gmane.linux.kernel,gmane.linux.file-systems -Subject: [PATCH 4/4] fuse: check create mode in atomic open -Date: Tue, 7 Aug 2012 14:45:49 +0200 -Lines: 29 -Approved: news@gmane.org -Message-ID: <1344343549-11887-5-git-send-email-miklos@szeredi.hu> -References: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -NNTP-Posting-Host: plane.gmane.org -X-Trace: dough.gmane.org 1344343501 28616 80.91.229.3 (7 Aug 2012 12:45:01 GMT) -X-Complaints-To: usenet@dough.gmane.org -NNTP-Posting-Date: Tue, 7 Aug 2012 12:45:01 +0000 (UTC) -Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, - rjones@redhat.com, steveamigauk@yahoo.co.uk, mszeredi@suse.cz -To: viro@ZenIV.linux.org.uk -Original-X-From: linux-kernel-owner@vger.kernel.org Tue Aug 07 14:45:01 2012 -Return-path: -Envelope-to: glk-linux-kernel-3@plane.gmane.org -Original-Received: from vger.kernel.org ([209.132.180.67]) - by plane.gmane.org with esmtp (Exim 4.69) - (envelope-from ) - id 1Syj9g-000751-AP - for glk-linux-kernel-3@plane.gmane.org; Tue, 07 Aug 2012 14:45:01 +0200 -Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S1753956Ab2HGMol (ORCPT ); - Tue, 7 Aug 2012 08:44:41 -0400 -Original-Received: from mail-wg0-f44.google.com ([74.125.82.44]:49113 "EHLO - mail-wg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S1754550Ab2HGMoi (ORCPT - ); - Tue, 7 Aug 2012 08:44:38 -0400 -Original-Received: by wgbdr13 with SMTP id dr13so3821771wgb.1 - for ; Tue, 07 Aug 2012 05:44:37 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=szeredi.hu; s=google; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; - bh=2z/lG+dElZX1BvzqKB7l/eTdQWJupcJMEPoo3E7WIkA=; - b=OSiFNFL8gGKzfQF4uTbT4uuk+FiRJFon3esY5HKXETPIldNkm2zTGUf0pTSAFKp+UG - nR1uDMgw8M+lY8aSepjpSqty+93LvJBEn5N2L+7hZeMPZHw/dvkjHpV/GvbqLI++oeHY - h5H4AqTI/51xQvAZP0fid7hVJh2leMo1lGtMc= -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20120113; - h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references - :x-gm-message-state; - bh=2z/lG+dElZX1BvzqKB7l/eTdQWJupcJMEPoo3E7WIkA=; - b=f5PRamaleMoVfPo7U0JjEgSltuT3/8qDvNRrgagcbsxz99IsBh5XZBfdcIX4BbAGYR - NNS0XMJEHgZSVE6O+imPLvlj3Oc7e4+NPYcfZTIeq3RdCpXeX5/X6woK4PJcOXIRMHML - U3L0o3trwK6EZTxyuThoOdptBVHQh+IyxzGJoHCSyoZki5ZMdjJUCnbLuOvY4A1xfaxM - a4v33nCxXl8B/698Hjm/U+Q5wIO2yloqCYTjzBeKquRsprxmLGfqErEqQSP7N7n2yGiV - cdiHfHOA2S0RbP+FTw9MRrW5he8tpeVbXodbYfrUazI0XruNSm3x09gttO8KhR0ehCSD - gshg== -Original-Received: by 10.216.134.101 with SMTP id r79mr6493496wei.60.1344343477315; - Tue, 07 Aug 2012 05:44:37 -0700 (PDT) -Original-Received: from localhost.localdomain (77-234-87-236.pool.digikabel.hu. [77.234.87.236]) - by mx.google.com with ESMTPS id b7sm31225742wiz.9.2012.08.07.05.44.35 - (version=TLSv1/SSLv3 cipher=OTHER); - Tue, 07 Aug 2012 05:44:36 -0700 (PDT) -X-Mailer: git-send-email 1.7.7 -In-Reply-To: <1344343549-11887-1-git-send-email-miklos@szeredi.hu> -X-Gm-Message-State: ALoCoQmdZRlhlKJWBzIDpgy+1szkaUFmK1NUhSopmYGukU6PHpk7xwsXWx0v+JWsNJdT/Aeqwz5M -Original-Sender: linux-kernel-owner@vger.kernel.org -Precedence: bulk -List-ID: -X-Mailing-List: linux-kernel@vger.kernel.org -Xref: news.gmane.org gmane.linux.kernel:1338998 gmane.linux.file-systems:66447 -Archived-At: - -From: Miklos Szeredi - -Verify that the VFS is passing us a complete create mode with the S_IFREG to -atomic open. - -Reported-by: Steve -Reported-by: Richard W.M. Jones -Signed-off-by: Miklos Szeredi ---- - fs/fuse/dir.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c -index 8964cf3..324bc08 100644 ---- a/fs/fuse/dir.c -+++ b/fs/fuse/dir.c -@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, - struct fuse_entry_out outentry; - struct fuse_file *ff; - -+ /* Userspace expects S_IFREG in create mode */ -+ BUG_ON((mode & S_IFMT) != S_IFREG); -+ - forget = fuse_alloc_forget(); - err = -ENOMEM; - if (!forget) --- -1.7.7 -