From 146aa8b1453bd8f1ff2304ffb71b4ee0eb9acdcc Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 21 Oct 2015 14:04:48 +0100 Subject: KEYS: Merge the type-specific data with the payload data Merge the type-specific data with the payload data into one four-word chunk as it seems pointless to keep them separate. Use user_key_payload() for accessing the payloads of overloaded user-defined keys. Signed-off-by: David Howells cc: linux-cifs@vger.kernel.org cc: ecryptfs@vger.kernel.org cc: linux-ext4@vger.kernel.org cc: linux-f2fs-devel@lists.sourceforge.net cc: linux-nfs@vger.kernel.org cc: ceph-devel@vger.kernel.org cc: linux-ima-devel@lists.sourceforge.net --- security/keys/big_key.c | 47 ++++++++++++++++-------- security/keys/encrypted-keys/encrypted.c | 18 ++++----- security/keys/encrypted-keys/encrypted.h | 4 +- security/keys/encrypted-keys/masterkey_trusted.c | 4 +- security/keys/key.c | 18 ++++----- security/keys/keyctl.c | 4 +- security/keys/keyring.c | 12 +++--- security/keys/process_keys.c | 4 +- security/keys/request_key.c | 4 +- security/keys/request_key_auth.c | 12 +++--- security/keys/trusted.c | 6 +-- security/keys/user_defined.c | 14 +++---- 12 files changed, 81 insertions(+), 66 deletions(-) (limited to 'security/keys') diff --git a/security/keys/big_key.c b/security/keys/big_key.c index b6adb94f6d52..907c1522ee46 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -20,6 +20,16 @@ MODULE_LICENSE("GPL"); +/* + * Layout of key payload words. + */ +enum { + big_key_data, + big_key_path, + big_key_path_2nd_part, + big_key_len, +}; + /* * If the data is under this limit, there's no point creating a shm file to * hold it as the permanently resident metadata for the shmem fs will be at @@ -47,7 +57,7 @@ struct key_type key_type_big_key = { */ int big_key_preparse(struct key_preparsed_payload *prep) { - struct path *path = (struct path *)&prep->payload; + struct path *path = (struct path *)&prep->payload.data[big_key_path]; struct file *file; ssize_t written; size_t datalen = prep->datalen; @@ -60,7 +70,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) /* Set an arbitrary quota */ prep->quotalen = 16; - prep->type_data[1] = (void *)(unsigned long)datalen; + prep->payload.data[big_key_len] = (void *)(unsigned long)datalen; if (datalen > BIG_KEY_FILE_THRESHOLD) { /* Create a shmem file to store the data in. This will permit the data @@ -94,7 +104,8 @@ int big_key_preparse(struct key_preparsed_payload *prep) if (!data) return -ENOMEM; - prep->payload[0] = memcpy(data, prep->data, prep->datalen); + prep->payload.data[big_key_data] = data; + memcpy(data, prep->data, prep->datalen); } return 0; @@ -110,10 +121,10 @@ error: void big_key_free_preparse(struct key_preparsed_payload *prep) { if (prep->datalen > BIG_KEY_FILE_THRESHOLD) { - struct path *path = (struct path *)&prep->payload; + struct path *path = (struct path *)&prep->payload.data[big_key_path]; path_put(path); } else { - kfree(prep->payload[0]); + kfree(prep->payload.data[big_key_data]); } } @@ -123,11 +134,12 @@ void big_key_free_preparse(struct key_preparsed_payload *prep) */ void big_key_revoke(struct key *key) { - struct path *path = (struct path *)&key->payload.data2; + struct path *path = (struct path *)&key->payload.data[big_key_path]; /* clear the quota */ key_payload_reserve(key, 0); - if (key_is_instantiated(key) && key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) + if (key_is_instantiated(key) && + (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) vfs_truncate(path, 0); } @@ -136,14 +148,16 @@ void big_key_revoke(struct key *key) */ void big_key_destroy(struct key *key) { - if (key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) { - struct path *path = (struct path *)&key->payload.data2; + size_t datalen = (size_t)key->payload.data[big_key_len]; + + if (datalen) { + struct path *path = (struct path *)&key->payload.data[big_key_path]; path_put(path); path->mnt = NULL; path->dentry = NULL; } else { - kfree(key->payload.data); - key->payload.data = NULL; + kfree(key->payload.data[big_key_data]); + key->payload.data[big_key_data] = NULL; } } @@ -152,12 +166,12 @@ void big_key_destroy(struct key *key) */ void big_key_describe(const struct key *key, struct seq_file *m) { - unsigned long datalen = key->type_data.x[1]; + size_t datalen = (size_t)key->payload.data[big_key_len]; seq_puts(m, key->description); if (key_is_instantiated(key)) - seq_printf(m, ": %lu [%s]", + seq_printf(m, ": %zu [%s]", datalen, datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); } @@ -168,14 +182,14 @@ void big_key_describe(const struct key *key, struct seq_file *m) */ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) { - unsigned long datalen = key->type_data.x[1]; + size_t datalen = (size_t)key->payload.data[big_key_len]; long ret; if (!buffer || buflen < datalen) return datalen; if (datalen > BIG_KEY_FILE_THRESHOLD) { - struct path *path = (struct path *)&key->payload.data2; + struct path *path = (struct path *)&key->payload.data[big_key_path]; struct file *file; loff_t pos; @@ -190,7 +204,8 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) ret = -EIO; } else { ret = datalen; - if (copy_to_user(buffer, key->payload.data, datalen) != 0) + if (copy_to_user(buffer, key->payload.data[big_key_data], + datalen) != 0) ret = -EFAULT; } diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 7bed4ad7cd76..927db9f35ad6 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@ -303,10 +303,10 @@ out: * * Use a user provided key to encrypt/decrypt an encrypted-key. */ -static struct key *request_user_key(const char *master_desc, u8 **master_key, +static struct key *request_user_key(const char *master_desc, const u8 **master_key, size_t *master_keylen) { - struct user_key_payload *upayload; + const struct user_key_payload *upayload; struct key *ukey; ukey = request_key(&key_type_user, master_desc, NULL); @@ -314,7 +314,7 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key, goto error; down_read(&ukey->sem); - upayload = ukey->payload.data; + upayload = user_key_payload(ukey); *master_key = upayload->data; *master_keylen = upayload->datalen; error: @@ -426,7 +426,7 @@ static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key, } static struct key *request_master_key(struct encrypted_key_payload *epayload, - u8 **master_key, size_t *master_keylen) + const u8 **master_key, size_t *master_keylen) { struct key *mkey = NULL; @@ -653,7 +653,7 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, { struct key *mkey; u8 derived_key[HASH_SIZE]; - u8 *master_key; + const u8 *master_key; u8 *hmac; const char *hex_encoded_data; unsigned int encrypted_datalen; @@ -837,7 +837,7 @@ static void encrypted_rcu_free(struct rcu_head *rcu) */ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) { - struct encrypted_key_payload *epayload = key->payload.data; + struct encrypted_key_payload *epayload = key->payload.data[0]; struct encrypted_key_payload *new_epayload; char *buf; char *new_master_desc = NULL; @@ -896,7 +896,7 @@ static long encrypted_read(const struct key *key, char __user *buffer, { struct encrypted_key_payload *epayload; struct key *mkey; - u8 *master_key; + const u8 *master_key; size_t master_keylen; char derived_key[HASH_SIZE]; char *ascii_buf; @@ -957,13 +957,13 @@ out: */ static void encrypted_destroy(struct key *key) { - struct encrypted_key_payload *epayload = key->payload.data; + struct encrypted_key_payload *epayload = key->payload.data[0]; if (!epayload) return; memset(epayload->decrypted_data, 0, epayload->decrypted_datalen); - kfree(key->payload.data); + kfree(key->payload.data[0]); } struct key_type key_type_encrypted = { diff --git a/security/keys/encrypted-keys/encrypted.h b/security/keys/encrypted-keys/encrypted.h index 8136a2d44c63..47802c0de735 100644 --- a/security/keys/encrypted-keys/encrypted.h +++ b/security/keys/encrypted-keys/encrypted.h @@ -5,10 +5,10 @@ #if defined(CONFIG_TRUSTED_KEYS) || \ (defined(CONFIG_TRUSTED_KEYS_MODULE) && defined(CONFIG_ENCRYPTED_KEYS_MODULE)) extern struct key *request_trusted_key(const char *trusted_desc, - u8 **master_key, size_t *master_keylen); + const u8 **master_key, size_t *master_keylen); #else static inline struct key *request_trusted_key(const char *trusted_desc, - u8 **master_key, + const u8 **master_key, size_t *master_keylen) { return ERR_PTR(-EOPNOTSUPP); diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c index 013f7e5d3a2f..b5b4812dbc87 100644 --- a/security/keys/encrypted-keys/masterkey_trusted.c +++ b/security/keys/encrypted-keys/masterkey_trusted.c @@ -29,7 +29,7 @@ * data, trusted key type data is not visible decrypted from userspace. */ struct key *request_trusted_key(const char *trusted_desc, - u8 **master_key, size_t *master_keylen) + const u8 **master_key, size_t *master_keylen) { struct trusted_key_payload *tpayload; struct key *tkey; @@ -39,7 +39,7 @@ struct key *request_trusted_key(const char *trusted_desc, goto error; down_read(&tkey->sem); - tpayload = tkey->payload.data; + tpayload = tkey->payload.data[0]; *master_key = tpayload->key; *master_keylen = tpayload->key_len; error: diff --git a/security/keys/key.c b/security/keys/key.c index c0478465d1ac..ab7997ded725 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -554,7 +554,7 @@ int key_reject_and_link(struct key *key, if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { /* mark the key as being negatively instantiated */ atomic_inc(&key->user->nikeys); - key->type_data.reject_error = -error; + key->reject_error = -error; smp_wmb(); set_bit(KEY_FLAG_NEGATIVE, &key->flags); set_bit(KEY_FLAG_INSTANTIATED, &key->flags); @@ -1046,14 +1046,14 @@ int generic_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 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]; - rcu_assign_keypointer(key, prep->payload[0]); - key->payload.data2[1] = prep->payload[1]; - prep->type_data[0] = NULL; - prep->type_data[1] = NULL; - prep->payload[0] = NULL; - prep->payload[1] = NULL; + rcu_assign_keypointer(key, prep->payload.data[0]); + key->payload.data[1] = prep->payload.data[1]; + key->payload.data[2] = prep->payload.data[2]; + key->payload.data[3] = prep->payload.data[3]; + prep->payload.data[0] = NULL; + prep->payload.data[1] = NULL; + prep->payload.data[2] = NULL; + prep->payload.data[3] = NULL; } pr_devel("<==%s() = %d\n", __func__, ret); return ret; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 6110fa498494..fb111eafcb89 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1027,7 +1027,7 @@ long keyctl_instantiate_key_common(key_serial_t id, if (!instkey) goto error; - rka = instkey->payload.data; + rka = instkey->payload.data[0]; if (rka->target_key->serial != id) goto error; @@ -1194,7 +1194,7 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error, if (!instkey) goto error; - rka = instkey->payload.data; + rka = instkey->payload.data[0]; if (rka->target_key->serial != id) goto error; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index d33437007ad2..f931ccfeefb0 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -118,7 +118,7 @@ static void keyring_publish_name(struct key *keyring) if (!keyring_name_hash[bucket].next) INIT_LIST_HEAD(&keyring_name_hash[bucket]); - list_add_tail(&keyring->type_data.link, + list_add_tail(&keyring->name_link, &keyring_name_hash[bucket]); write_unlock(&keyring_name_lock); @@ -387,9 +387,9 @@ static void keyring_destroy(struct key *keyring) if (keyring->description) { write_lock(&keyring_name_lock); - if (keyring->type_data.link.next != NULL && - !list_empty(&keyring->type_data.link)) - list_del(&keyring->type_data.link); + if (keyring->name_link.next != NULL && + !list_empty(&keyring->name_link)) + list_del(&keyring->name_link); write_unlock(&keyring_name_lock); } @@ -572,7 +572,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) /* we set a different error code if we pass a negative key */ if (kflags & (1 << KEY_FLAG_NEGATIVE)) { smp_rmb(); - ctx->result = ERR_PTR(key->type_data.reject_error); + ctx->result = ERR_PTR(key->reject_error); kleave(" = %d [neg]", ctx->skipped_ret); goto skipped; } @@ -990,7 +990,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check) * that's readable and that hasn't been revoked */ list_for_each_entry(keyring, &keyring_name_hash[bucket], - type_data.link + name_link ) { if (!kuid_has_mapping(current_user_ns(), keyring->user->uid)) continue; diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 43b4cddbf2b3..a3f85d2a00bb 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -457,7 +457,7 @@ key_ref_t search_process_keyrings(struct keyring_search_context *ctx) down_read(&cred->request_key_auth->sem); if (key_validate(ctx->cred->request_key_auth) == 0) { - rka = ctx->cred->request_key_auth->payload.data; + rka = ctx->cred->request_key_auth->payload.data[0]; ctx->cred = rka->cred; key_ref = search_process_keyrings(ctx); @@ -647,7 +647,7 @@ try_again: key_ref = ERR_PTR(-EKEYREVOKED); key = NULL; } else { - rka = ctx.cred->request_key_auth->payload.data; + rka = ctx.cred->request_key_auth->payload.data[0]; key = rka->dest_keyring; __key_get(key); } diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 486ef6fa393b..95d5cfc172c6 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -271,7 +271,7 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) if (cred->request_key_auth) { authkey = cred->request_key_auth; down_read(&authkey->sem); - rka = authkey->payload.data; + rka = authkey->payload.data[0]; if (!test_bit(KEY_FLAG_REVOKED, &authkey->flags)) dest_keyring = @@ -593,7 +593,7 @@ int wait_for_key_construction(struct key *key, bool intr) return -ERESTARTSYS; if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { smp_rmb(); - return key->type_data.reject_error; + return key->reject_error; } return key_validate(key); } diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 5d672f7580dd..4f0f112fe276 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -59,7 +59,7 @@ static void request_key_auth_free_preparse(struct key_preparsed_payload *prep) static int request_key_auth_instantiate(struct key *key, struct key_preparsed_payload *prep) { - key->payload.data = (struct request_key_auth *)prep->data; + key->payload.data[0] = (struct request_key_auth *)prep->data; return 0; } @@ -69,7 +69,7 @@ static int request_key_auth_instantiate(struct key *key, static void request_key_auth_describe(const struct key *key, struct seq_file *m) { - struct request_key_auth *rka = key->payload.data; + struct request_key_auth *rka = key->payload.data[0]; seq_puts(m, "key:"); seq_puts(m, key->description); @@ -84,7 +84,7 @@ static void request_key_auth_describe(const struct key *key, static long request_key_auth_read(const struct key *key, char __user *buffer, size_t buflen) { - struct request_key_auth *rka = key->payload.data; + struct request_key_auth *rka = key->payload.data[0]; size_t datalen; long ret; @@ -110,7 +110,7 @@ static long request_key_auth_read(const struct key *key, */ static void request_key_auth_revoke(struct key *key) { - struct request_key_auth *rka = key->payload.data; + struct request_key_auth *rka = key->payload.data[0]; kenter("{%d}", key->serial); @@ -125,7 +125,7 @@ static void request_key_auth_revoke(struct key *key) */ static void request_key_auth_destroy(struct key *key) { - struct request_key_auth *rka = key->payload.data; + struct request_key_auth *rka = key->payload.data[0]; kenter("{%d}", key->serial); @@ -179,7 +179,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags)) goto auth_key_revoked; - irka = cred->request_key_auth->payload.data; + irka = cred->request_key_auth->payload.data[0]; rka->cred = get_cred(irka->cred); rka->pid = irka->pid; diff --git a/security/keys/trusted.c b/security/keys/trusted.c index d3633cf17c7d..903dace648a1 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -1007,7 +1007,7 @@ static void trusted_rcu_free(struct rcu_head *rcu) */ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) { - struct trusted_key_payload *p = key->payload.data; + struct trusted_key_payload *p = key->payload.data[0]; struct trusted_key_payload *new_p; struct trusted_key_options *new_o; size_t datalen = prep->datalen; @@ -1114,12 +1114,12 @@ static long trusted_read(const struct key *key, char __user *buffer, */ static void trusted_destroy(struct key *key) { - struct trusted_key_payload *p = key->payload.data; + struct trusted_key_payload *p = key->payload.data[0]; if (!p) return; memset(p->key, 0, p->key_len); - kfree(key->payload.data); + kfree(key->payload.data[0]); } struct key_type key_type_trusted = { diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index 36b47bbd3d8c..28cb30f80256 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -74,7 +74,7 @@ int user_preparse(struct key_preparsed_payload *prep) /* attach the data */ prep->quotalen = datalen; - prep->payload[0] = upayload; + prep->payload.data[0] = upayload; upayload->datalen = datalen; memcpy(upayload->data, prep->data, datalen); return 0; @@ -86,7 +86,7 @@ EXPORT_SYMBOL_GPL(user_preparse); */ void user_free_preparse(struct key_preparsed_payload *prep) { - kfree(prep->payload[0]); + kfree(prep->payload.data[0]); } EXPORT_SYMBOL_GPL(user_free_preparse); @@ -120,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) if (ret == 0) { /* attach the new data, displacing the old */ - zap = key->payload.data; + zap = key->payload.data[0]; rcu_assign_keypointer(key, upayload); key->expiry = 0; } @@ -140,7 +140,7 @@ EXPORT_SYMBOL_GPL(user_update); */ void user_revoke(struct key *key) { - struct user_key_payload *upayload = key->payload.data; + struct user_key_payload *upayload = key->payload.data[0]; /* clear the quota */ key_payload_reserve(key, 0); @@ -158,7 +158,7 @@ EXPORT_SYMBOL(user_revoke); */ void user_destroy(struct key *key) { - struct user_key_payload *upayload = key->payload.data; + struct user_key_payload *upayload = key->payload.data[0]; kfree(upayload); } @@ -183,10 +183,10 @@ EXPORT_SYMBOL_GPL(user_describe); */ long user_read(const struct key *key, char __user *buffer, size_t buflen) { - struct user_key_payload *upayload; + const struct user_key_payload *upayload; long ret; - upayload = rcu_dereference_key(key); + upayload = user_key_payload(key); ret = upayload->datalen; /* we can return the data as is */ -- cgit v1.2.3-59-g8ed1b