KEYS: Merge the type-specific data with the payload data
authorDavid Howells <dhowells@redhat.com>
Wed, 21 Oct 2015 13:04:48 +0000 (14:04 +0100)
committerDavid Howells <dhowells@redhat.com>
Wed, 21 Oct 2015 14:18:36 +0000 (15:18 +0100)
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 <dhowells@redhat.com>
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

49 files changed:
Documentation/crypto/asymmetric-keys.txt
Documentation/security/keys.txt
crypto/asymmetric_keys/asymmetric_keys.h
crypto/asymmetric_keys/asymmetric_type.c
crypto/asymmetric_keys/public_key.c
crypto/asymmetric_keys/signature.c
crypto/asymmetric_keys/x509_parser.h
crypto/asymmetric_keys/x509_public_key.c
fs/cifs/cifs_spnego.c
fs/cifs/cifsacl.c
fs/cifs/connect.c
fs/cifs/sess.c
fs/cifs/smb2pdu.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ext4/crypto_key.c
fs/f2fs/crypto_key.c
fs/fscache/object-list.c
fs/nfs/nfs4idmap.c
include/crypto/public_key.h
include/keys/asymmetric-subtype.h
include/keys/asymmetric-type.h
include/keys/user-type.h
include/linux/key-type.h
include/linux/key.h
kernel/module_signing.c
lib/digsig.c
net/ceph/ceph_common.c
net/ceph/crypto.c
net/dns_resolver/dns_key.c
net/dns_resolver/dns_query.c
net/dns_resolver/internal.h
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-key.c
net/rxrpc/ar-output.c
net/rxrpc/ar-security.c
net/rxrpc/rxkad.c
security/integrity/evm/evm_crypto.c
security/keys/big_key.c
security/keys/encrypted-keys/encrypted.c
security/keys/encrypted-keys/encrypted.h
security/keys/encrypted-keys/masterkey_trusted.c
security/keys/key.c
security/keys/keyctl.c
security/keys/keyring.c
security/keys/process_keys.c
security/keys/request_key.c
security/keys/request_key_auth.c
security/keys/trusted.c
security/keys/user_defined.c

index b7675904a7478a4d52fc2d23b4157adcdd132761..8c07e0ea6bc0e49552f6c5b264cc4404773d629d 100644 (file)
@@ -186,7 +186,7 @@ and looks like the following:
                                        const struct public_key_signature *sig);
        };
 
-Asymmetric keys point to this with their type_data[0] member.
+Asymmetric keys point to this with their payload[asym_subtype] member.
 
 The owner and name fields should be set to the owning module and the name of
 the subtype.  Currently, the name is only used for print statements.
@@ -269,8 +269,7 @@ mandatory:
 
        struct key_preparsed_payload {
                char            *description;
-               void            *type_data[2];
-               void            *payload;
+               void            *payload[4];
                const void      *data;
                size_t          datalen;
                size_t          quotalen;
@@ -283,16 +282,18 @@ mandatory:
      not theirs.
 
      If the parser is happy with the blob, it should propose a description for
-     the key and attach it to ->description, ->type_data[0] should be set to
-     point to the subtype to be used, ->payload should be set to point to the
-     initialised data for that subtype, ->type_data[1] should point to a hex
-     fingerprint and quotalen should be updated to indicate how much quota this
-     key should account for.
-
-     When clearing up, the data attached to ->type_data[1] and ->description
-     will be kfree()'d and the data attached to ->payload will be passed to the
-     subtype's ->destroy() method to be disposed of.  A module reference for
-     the subtype pointed to by ->type_data[0] will be put.
+     the key and attach it to ->description, ->payload[asym_subtype] should be
+     set to point to the subtype to be used, ->payload[asym_crypto] should be
+     set to point to the initialised data for that subtype,
+     ->payload[asym_key_ids] should point to one or more hex fingerprints and
+     quotalen should be updated to indicate how much quota this key should
+     account for.
+
+     When clearing up, the data attached to ->payload[asym_key_ids] and
+     ->description will be kfree()'d and the data attached to
+     ->payload[asm_crypto] will be passed to the subtype's ->destroy() method
+     to be disposed of.  A module reference for the subtype pointed to by
+     ->payload[asym_subtype] will be put.
 
 
      If the data format is not recognised, -EBADMSG should be returned.  If it
index c9e7f4f223a55b6fed9e740cc2f17a4a773e02da..8c183873b2b77f771deb13dd74c21c49e19ec5ed 100644 (file)
@@ -1049,12 +1049,12 @@ search a specific keyring, so using keyrings in this way is of limited utility.
 NOTES ON ACCESSING PAYLOAD CONTENTS
 ===================================
 
-The simplest payload is just a number in key->payload.value. In this case,
-there's no need to indulge in RCU or locking when accessing the payload.
+The simplest payload is just data stored in key->payload directly.  In this
+case, there's no need to indulge in RCU or locking when accessing the payload.
 
-More complex payload contents must be allocated and a pointer to them set in
-key->payload.data. One of the following ways must be selected to access the
-data:
+More complex payload contents must be allocated and pointers to them set in the
+key->payload.data[] array.  One of the following ways must be selected to
+access the data:
 
  (1) Unmodifiable key type.
 
@@ -1092,6 +1092,13 @@ data:
      the payload. key->datalen cannot be relied upon to be consistent with the
      payload just dereferenced if the key's semaphore is not held.
 
+     Note that key->payload.data[0] has a shadow that is marked for __rcu
+     usage.  This is called key->payload.rcu_data0.  The following accessors
+     wrap the RCU calls to this element:
+
+       rcu_assign_keypointer(struct key *key, void *data);
+       void *rcu_dereference_key(struct key *key);
+
 
 ===================
 DEFINING A KEY TYPE
@@ -1143,8 +1150,7 @@ The structure has a number of fields, some of which are mandatory:
 
        struct key_preparsed_payload {
                char            *description;
-               void            *type_data[2];
-               void            *payload;
+               union key_payload payload;
                const void      *data;
                size_t          datalen;
                size_t          quotalen;
@@ -1160,10 +1166,9 @@ The structure has a number of fields, some of which are mandatory:
      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.  If
-     set, the expiry time will be applied to the key if it is instantiated from
-     this data.
+     The method can attach anything it likes to payload.  This is merely passed
+     along to the instantiate() or update() operations.  If set, the expiry
+     time will be applied to the key if it is instantiated from this data.
 
      The method should return 0 if successful or a negative error code
      otherwise.
@@ -1172,11 +1177,10 @@ The structure has a number of fields, some of which are mandatory:
  (*) 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.  It will always be called
-     after preparse() returns successfully, even if instantiate() or update()
-     succeed.
+     otherwise it is unused.  It cleans up anything attached to the description
+     and payload fields of the key_preparsed_payload struct as filled in by the
+     preparse() method.  It will always be called after preparse() returns
+     successfully, even if instantiate() or update() succeed.
 
 
  (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
@@ -1197,6 +1201,11 @@ The structure has a number of fields, some of which are mandatory:
 
      It is safe to sleep in this method.
 
+     generic_key_instantiate() is provided to simply copy the data from
+     prep->payload.data[] to key->payload.data[], with RCU-safe assignment on
+     the first element.  It will then clear prep->payload.data[] so that the
+     free_preparse method doesn't release the data.
+
 
  (*) int (*update)(struct key *key, const void *data, size_t datalen);
 
index 3f5b537ab33ec36f640ca6ca61038ba8390fda22..1d450b580245157b500db100de8576f4027bf030 100644 (file)
@@ -14,8 +14,3 @@ extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
 extern int __asymmetric_key_hex_to_key_id(const char *id,
                                          struct asymmetric_key_id *match_id,
                                          size_t hexlen);
-static inline
-const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
-{
-       return key->type_data.p[1];
-}
index 1916680ad81b08fc6db5a0f9f2751dc0526b3e9b..9f2165b27d52efe6fcae3c64956a2c717a3d93da 100644 (file)
@@ -306,26 +306,35 @@ static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
        return ret;
 }
 
+/*
+ * Clean up the key ID list
+ */
+static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids)
+{
+       int i;
+
+       if (kids) {
+               for (i = 0; i < ARRAY_SIZE(kids->id); i++)
+                       kfree(kids->id[i]);
+               kfree(kids);
+       }
+}
+
 /*
  * Clean up the preparse data
  */
 static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
 {
-       struct asymmetric_key_subtype *subtype = prep->type_data[0];
-       struct asymmetric_key_ids *kids = prep->type_data[1];
-       int i;
+       struct asymmetric_key_subtype *subtype = prep->payload.data[asym_subtype];
+       struct asymmetric_key_ids *kids = prep->payload.data[asym_key_ids];
 
        pr_devel("==>%s()\n", __func__);
 
        if (subtype) {
-               subtype->destroy(prep->payload[0]);
+               subtype->destroy(prep->payload.data[asym_crypto]);
                module_put(subtype->owner);
        }
-       if (kids) {
-               for (i = 0; i < ARRAY_SIZE(kids->id); i++)
-                       kfree(kids->id[i]);
-               kfree(kids);
-       }
+       asymmetric_key_free_kids(kids);
        kfree(prep->description);
 }
 
@@ -335,20 +344,19 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
 static void asymmetric_key_destroy(struct key *key)
 {
        struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
-       struct asymmetric_key_ids *kids = key->type_data.p[1];
+       struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids];
+       void *data = key->payload.data[asym_crypto];
+
+       key->payload.data[asym_crypto] = NULL;
+       key->payload.data[asym_subtype] = NULL;
+       key->payload.data[asym_key_ids] = NULL;
 
        if (subtype) {
-               subtype->destroy(key->payload.data);
+               subtype->destroy(data);
                module_put(subtype->owner);
-               key->type_data.p[0] = NULL;
        }
 
-       if (kids) {
-               kfree(kids->id[0]);
-               kfree(kids->id[1]);
-               kfree(kids);
-               key->type_data.p[1] = NULL;
-       }
+       asymmetric_key_free_kids(kids);
 }
 
 struct key_type key_type_asymmetric = {
index 81efccbe22d5b21d3e31e44f504fc23cefd32d76..6db4c01c6503ff267e0d7ecbe4dbf09496743c15 100644 (file)
@@ -49,7 +49,7 @@ EXPORT_SYMBOL_GPL(pkey_id_type_name);
 static void public_key_describe(const struct key *asymmetric_key,
                                struct seq_file *m)
 {
-       struct public_key *key = asymmetric_key->payload.data;
+       struct public_key *key = asymmetric_key->payload.data[asym_crypto];
 
        if (key)
                seq_printf(m, "%s.%s",
@@ -112,7 +112,7 @@ EXPORT_SYMBOL_GPL(public_key_verify_signature);
 static int public_key_verify_signature_2(const struct key *key,
                                         const struct public_key_signature *sig)
 {
-       const struct public_key *pk = key->payload.data;
+       const struct public_key *pk = key->payload.data[asym_crypto];
        return public_key_verify_signature(pk, sig);
 }
 
index 7525fd183574c826b2f85a5f4de3ba47e4c585ab..9441240f7d2a51e746331dc8aa720ae4280685e4 100644 (file)
@@ -37,7 +37,7 @@ int verify_signature(const struct key *key,
                return -EINVAL;
        subtype = asymmetric_key_subtype(key);
        if (!subtype ||
-           !key->payload.data)
+           !key->payload.data[0])
                return -EINVAL;
        if (!subtype->verify_signature)
                return -ENOTSUPP;
index 1de01eaec88490c6c24d669a6f02c6b4fc2e9959..dbeed6018e63675db5316e254760f10e4a28a2b4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/time.h>
 #include <crypto/public_key.h>
+#include <keys/asymmetric-type.h>
 
 struct x509_certificate {
        struct x509_certificate *next;
index 19709663241223968ee73f3d1847be9e253969f7..64d42981a8d741e488f0986d144ed7fa1515e74b 100644 (file)
@@ -266,7 +266,8 @@ static int x509_validate_trust(struct x509_certificate *cert,
        if (!IS_ERR(key))  {
                if (!use_builtin_keys
                    || test_bit(KEY_FLAG_BUILTIN, &key->flags))
-                       ret = x509_check_signature(key->payload.data, cert);
+                       ret = x509_check_signature(key->payload.data[asym_crypto],
+                                                  cert);
                key_put(key);
        }
        return ret;
@@ -352,9 +353,9 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
 
        /* We're pinning the module by being linked against it */
        __module_get(public_key_subtype.owner);
-       prep->type_data[0] = &public_key_subtype;
-       prep->type_data[1] = kids;
-       prep->payload[0] = cert->pub;
+       prep->payload.data[asym_subtype] = &public_key_subtype;
+       prep->payload.data[asym_key_ids] = kids;
+       prep->payload.data[asym_crypto] = cert->pub;
        prep->description = desc;
        prep->quotalen = 100;
 
index f4cf200b3c76714ca5a059b1ecdcca6f2e77b338..6908080e9b6d889f323d21da24892046f7fd16a0 100644 (file)
@@ -42,7 +42,7 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
                goto error;
 
        /* attach the data */
-       key->payload.data = payload;
+       key->payload.data[0] = payload;
        ret = 0;
 
 error:
@@ -52,7 +52,7 @@ error:
 static void
 cifs_spnego_key_destroy(struct key *key)
 {
-       kfree(key->payload.data);
+       kfree(key->payload.data[0]);
 }
 
 
@@ -167,7 +167,7 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
 
 #ifdef CONFIG_CIFS_DEBUG2
        if (cifsFYI && !IS_ERR(spnego_key)) {
-               struct cifs_spnego_msg *msg = spnego_key->payload.data;
+               struct cifs_spnego_msg *msg = spnego_key->payload.data[0];
                cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U,
                                msg->secblob_len + msg->sesskey_len));
        }
index 1ea780bc6376ed00fe39d211b82ea01c30f2ad57..3f93125916bf041e824e0d98df07c7b8195abdf3 100644 (file)
@@ -58,16 +58,15 @@ cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
         * dereference payload.data!
         */
        if (prep->datalen <= sizeof(key->payload)) {
-               key->payload.value = 0;
-               memcpy(&key->payload.value, prep->data, prep->datalen);
-               key->datalen = prep->datalen;
-               return 0;
+               key->payload.data[0] = NULL;
+               memcpy(&key->payload, prep->data, prep->datalen);
+       } else {
+               payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
+               if (!payload)
+                       return -ENOMEM;
+               key->payload.data[0] = payload;
        }
-       payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
-       if (!payload)
-               return -ENOMEM;
 
-       key->payload.data = payload;
        key->datalen = prep->datalen;
        return 0;
 }
@@ -76,7 +75,7 @@ static inline void
 cifs_idmap_key_destroy(struct key *key)
 {
        if (key->datalen > sizeof(key->payload))
-               kfree(key->payload.data);
+               kfree(key->payload.data[0]);
 }
 
 static struct key_type cifs_idmap_key_type = {
@@ -233,8 +232,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
         * it could be.
         */
        ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
-               (struct cifs_sid *)&sidkey->payload.value :
-               (struct cifs_sid *)sidkey->payload.data;
+               (struct cifs_sid *)&sidkey->payload :
+               (struct cifs_sid *)sidkey->payload.data[0];
 
        ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
        if (ksid_size > sidkey->datalen) {
@@ -307,14 +306,14 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
        if (sidtype == SIDOWNER) {
                kuid_t uid;
                uid_t id;
-               memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
+               memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
                uid = make_kuid(&init_user_ns, id);
                if (uid_valid(uid))
                        fuid = uid;
        } else {
                kgid_t gid;
                gid_t id;
-               memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
+               memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
                gid = make_kgid(&init_user_ns, id);
                if (gid_valid(gid))
                        fgid = gid;
index 773f4dc776305284f4df53e4d4e44741a74b467f..3f2228570d441840b7e6d11c10a3b814a2b60962 100644 (file)
@@ -2325,13 +2325,14 @@ static int
 cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
 {
        int rc = 0;
-       char *desc, *delim, *payload;
+       const char *delim, *payload;
+       char *desc;
        ssize_t len;
        struct key *key;
        struct TCP_Server_Info *server = ses->server;
        struct sockaddr_in *sa;
        struct sockaddr_in6 *sa6;
-       struct user_key_payload *upayload;
+       const struct user_key_payload *upayload;
 
        desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
        if (!desc)
@@ -2374,14 +2375,14 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
        }
 
        down_read(&key->sem);
-       upayload = key->payload.data;
+       upayload = user_key_payload(key);
        if (IS_ERR_OR_NULL(upayload)) {
                rc = upayload ? PTR_ERR(upayload) : -EINVAL;
                goto out_key_put;
        }
 
        /* find first : in payload */
-       payload = (char *)upayload->data;
+       payload = upayload->data;
        delim = strnchr(payload, upayload->datalen, ':');
        cifs_dbg(FYI, "payload=%s\n", payload);
        if (!delim) {
index bce6fdcd5d480c8b7acb30e8f4bb329f61900151..59727e32ed0f68871785b17b0df0f41bf9e4f378 100644 (file)
@@ -988,7 +988,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
                goto out;
        }
 
-       msg = spnego_key->payload.data;
+       msg = spnego_key->payload.data[0];
        /*
         * check version field to make sure that cifs.upcall is
         * sending us a response in an expected form
index ce83e2edbe0a22ae9858ec5a04caa4e2b6ad59d2..52d14c9cf0522e3bf3afc1627cf6a2e57a378781 100644 (file)
@@ -660,7 +660,7 @@ ssetup_ntlmssp_authenticate:
                        goto ssetup_exit;
                }
 
-               msg = spnego_key->payload.data;
+               msg = spnego_key->payload.data[0];
                /*
                 * check version field to make sure that cifs.upcall is
                 * sending us a response in an expected form
index 5ba029e627cc22db0648317a619685e545977316..7b39260c7bbaa18fda583426a101a95124639dc5 100644 (file)
@@ -86,7 +86,7 @@ ecryptfs_get_encrypted_key_payload_data(struct key *key)
 {
        if (key->type == &key_type_encrypted)
                return (struct ecryptfs_auth_tok *)
-                       (&((struct encrypted_key_payload *)key->payload.data)->payload_data);
+                       (&((struct encrypted_key_payload *)key->payload.data[0])->payload_data);
        else
                return NULL;
 }
@@ -117,8 +117,7 @@ ecryptfs_get_key_payload_data(struct key *key)
 
        auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
        if (!auth_tok)
-               return (struct ecryptfs_auth_tok *)
-                       (((struct user_key_payload *)key->payload.data)->data);
+               return (struct ecryptfs_auth_tok *)user_key_payload(key)->data;
        else
                return auth_tok;
 }
index 1d510c11b100cf3eb8a1cdcafa9131a94e3841bb..5c52c79dea4625c4a73d7d6195da9c1e39d6f02b 100644 (file)
@@ -121,7 +121,7 @@ int _ext4_get_encryption_info(struct inode *inode)
        struct key *keyring_key = NULL;
        struct ext4_encryption_key *master_key;
        struct ext4_encryption_context ctx;
-       struct user_key_payload *ukp;
+       const struct user_key_payload *ukp;
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        struct crypto_ablkcipher *ctfm;
        const char *cipher_str;
@@ -209,7 +209,7 @@ retry:
        }
        crypt_info->ci_keyring_key = keyring_key;
        BUG_ON(keyring_key->type != &key_type_logon);
-       ukp = ((struct user_key_payload *)keyring_key->payload.data);
+       ukp = user_key_payload(keyring_key);
        if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
                res = -EINVAL;
                goto out;
index 9f77de2ef317e538ced76d5472c62df4de29fcaf..5de2d866a25c282fecb2bdf4592bc53fafa0ca85 100644 (file)
@@ -122,7 +122,7 @@ int _f2fs_get_encryption_info(struct inode *inode)
        struct key *keyring_key = NULL;
        struct f2fs_encryption_key *master_key;
        struct f2fs_encryption_context ctx;
-       struct user_key_payload *ukp;
+       const struct user_key_payload *ukp;
        struct crypto_ablkcipher *ctfm;
        const char *cipher_str;
        char raw_key[F2FS_MAX_KEY_SIZE];
@@ -199,7 +199,7 @@ retry:
        }
        crypt_info->ci_keyring_key = keyring_key;
        BUG_ON(keyring_key->type != &key_type_logon);
-       ukp = ((struct user_key_payload *)keyring_key->payload.data);
+       ukp = user_key_payload(keyring_key);
        if (ukp->datalen != sizeof(struct f2fs_encryption_key)) {
                res = -EINVAL;
                goto out;
index 51dde817e1f24aadc445d17ef19f8256879cf0cf..6b028b7c42509b6cdf319ea3513679c33cf57fc4 100644 (file)
@@ -316,7 +316,7 @@ static const struct seq_operations fscache_objlist_ops = {
 static void fscache_objlist_config(struct fscache_objlist_data *data)
 {
 #ifdef CONFIG_KEYS
-       struct user_key_payload *confkey;
+       const struct user_key_payload *confkey;
        unsigned long config;
        struct key *key;
        const char *buf;
@@ -329,7 +329,7 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
        config = 0;
        rcu_read_lock();
 
-       confkey = key->payload.data;
+       confkey = user_key_payload(key);
        buf = confkey->data;
 
        for (len = confkey->datalen - 1; len >= 0; len--) {
index 2e4902203c358c46344338ee2efcfb7db7aba7f7..5ba22c6b0ffa6d8bafb302c2660b56f1992fd792 100644 (file)
@@ -297,7 +297,7 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
 {
        const struct cred *saved_cred;
        struct key *rkey;
-       struct user_key_payload *payload;
+       const struct user_key_payload *payload;
        ssize_t ret;
 
        saved_cred = override_creds(id_resolver_cache);
@@ -316,7 +316,7 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
        if (ret < 0)
                goto out_up;
 
-       payload = rcu_dereference(rkey->payload.rcudata);
+       payload = user_key_payload(rkey);
        if (IS_ERR_OR_NULL(payload)) {
                ret = PTR_ERR(payload);
                goto out_up;
index 067c242b1e152d013f746424ceebd417112154a7..cc2516df0efac72d43ddde2a055fa88c38f2ece5 100644 (file)
@@ -15,7 +15,6 @@
 #define _LINUX_PUBLIC_KEY_H
 
 #include <linux/mpi.h>
-#include <keys/asymmetric-type.h>
 #include <crypto/hash_info.h>
 
 enum pkey_algo {
index 4b840e822209d7d6894f81476267655498d530f2..4915d40d3c3cf9d5c44a6c0663f277c01eaf8eaa 100644 (file)
@@ -49,7 +49,7 @@ struct asymmetric_key_subtype {
 static inline
 struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key)
 {
-       return key->type_data.p[0];
+       return key->payload.data[asym_subtype];
 }
 
 #endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */
index c0754abb2f5676b8d8df7c0df4d44efdc3767d48..59c1df9cf922dfd7f3da0ad251dea1a8c0494866 100644 (file)
 
 extern struct key_type key_type_asymmetric;
 
+/*
+ * The key payload is four words.  The asymmetric-type key uses them as
+ * follows:
+ */
+enum asymmetric_payload_bits {
+       asym_crypto,
+       asym_subtype,
+       asym_key_ids,
+};
+
 /*
  * Identifiers for an asymmetric key ID.  We have three ways of looking up a
  * key derived from an X.509 certificate:
@@ -58,6 +68,11 @@ extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
                                                            size_t len_1,
                                                            const void *val_2,
                                                            size_t len_2);
+static inline
+const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
+{
+       return key->payload.data[asym_key_ids];
+}
 
 /*
  * The payload is at the discretion of the subtype.
index cebefb069c44a51bed96e7fc671f0e839bf94d6a..c56fef40f53efa474a57303f46f773863e2fa4b9 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/key.h>
 #include <linux/rcupdate.h>
 
+#ifdef CONFIG_KEYS
+
 /*****************************************************************************/
 /*
  * the payload for a key of type "user" or "logon"
@@ -46,5 +48,11 @@ extern void user_describe(const struct key *user, struct seq_file *m);
 extern long user_read(const struct key *key,
                      char __user *buffer, size_t buflen);
 
+static inline const struct user_key_payload *user_key_payload(const struct key *key)
+{
+       return (struct user_key_payload *)rcu_dereference_key(key);
+}
+
+#endif /* CONFIG_KEYS */
 
 #endif /* _KEYS_USER_TYPE_H */
index ff9f1d3942356ffd1f16ab777cb8c7ed201b35e8..7463355a198b2326ce8c0b2aecd72baa8cd6f956 100644 (file)
@@ -40,8 +40,7 @@ struct key_construction {
  */
 struct key_preparsed_payload {
        char            *description;   /* Proposed key description (or NULL) */
-       void            *type_data[2];  /* Private key-type data */
-       void            *payload[2];    /* Proposed payload */
+       union key_payload payload;      /* Proposed payload */
        const void      *data;          /* Raw data */
        size_t          datalen;        /* Raw datalen */
        size_t          quotalen;       /* Quota length for proposed payload */
index e1d4715f322251591d7261a77e57f7e659c06881..66f70524398594598fb721cf284ebdf1403d8566 100644 (file)
@@ -89,6 +89,11 @@ struct keyring_index_key {
        size_t                  desc_len;
 };
 
+union key_payload {
+       void __rcu              *rcu_data0;
+       void                    *data[4];
+};
+
 /*****************************************************************************/
 /*
  * key reference with possession attribute handling
@@ -186,28 +191,18 @@ struct key {
                };
        };
 
-       /* type specific data
-        * - this is used by the keyring type to index the name
-        */
-       union {
-               struct list_head        link;
-               unsigned long           x[2];
-               void                    *p[2];
-               int                     reject_error;
-       } type_data;
-
        /* key data
         * - this is used to hold the data actually used in cryptography or
         *   whatever
         */
        union {
-               union {
-                       unsigned long           value;
-                       void __rcu              *rcudata;
-                       void                    *data;
-                       void                    *data2[2];
-               } payload;
-               struct assoc_array keys;
+               union key_payload payload;
+               struct {
+                       /* Keyring bits */
+                       struct list_head name_link;
+                       struct assoc_array keys;
+               };
+               int reject_error;
        };
 };
 
@@ -336,12 +331,12 @@ static inline bool key_is_instantiated(const struct key *key)
 }
 
 #define rcu_dereference_key(KEY)                                       \
-       (rcu_dereference_protected((KEY)->payload.rcudata,              \
+       (rcu_dereference_protected((KEY)->payload.rcu_data0,            \
                                   rwsem_is_locked(&((struct key *)(KEY))->sem)))
 
 #define rcu_assign_keypointer(KEY, PAYLOAD)                            \
 do {                                                                   \
-       rcu_assign_pointer((KEY)->payload.rcudata, (PAYLOAD));          \
+       rcu_assign_pointer((KEY)->payload.rcu_data0, (PAYLOAD));        \
 } while (0)
 
 #ifdef CONFIG_SYSCTL
index bd62f5cda74673377ef080c718163917387ddde0..6528a79d998d08120e9e80524164e5c759d911f3 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/errno.h>
 #include <keys/system_keyring.h>
 #include <crypto/public_key.h>
 #include "module-internal.h"
index ae05ea393fc8c10f5cd25f88a9c39e3d3f866680..07be6c1ef4e2564c321b7bda1669fc1e9d84f8cf 100644 (file)
@@ -79,12 +79,13 @@ static int digsig_verify_rsa(struct key *key,
        unsigned char *out1 = NULL;
        const char *m;
        MPI in = NULL, res = NULL, pkey[2];
-       uint8_t *p, *datap, *endp;
-       struct user_key_payload *ukp;
+       uint8_t *p, *datap;
+       const uint8_t *endp;
+       const struct user_key_payload *ukp;
        struct pubkey_hdr *pkh;
 
        down_read(&key->sem);
-       ukp = key->payload.data;
+       ukp = user_key_payload(key);
 
        if (ukp->datalen < sizeof(*pkh))
                goto err1;
index 54a00d66509e748d47068a664bc14585166cbd97..78f098a20796d7dd0d71b364c5de3d99239dc4ac 100644 (file)
@@ -318,7 +318,7 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
                goto out;
        }
 
-       ckey = ukey->payload.data;
+       ckey = ukey->payload.data[0];
        err = ceph_crypto_key_clone(dst, ckey);
        if (err)
                goto out_key;
index 4440edcce0d6c0fd427fe5e5b456dd67de7e8e52..42e8649c6e79b4950531f0027f2e67820377c066 100644 (file)
@@ -537,7 +537,7 @@ static int ceph_key_preparse(struct key_preparsed_payload *prep)
        if (ret < 0)
                goto err_ckey;
 
-       prep->payload[0] = ckey;
+       prep->payload.data[0] = ckey;
        prep->quotalen = datalen;
        return 0;
 
@@ -549,14 +549,14 @@ err:
 
 static void ceph_key_free_preparse(struct key_preparsed_payload *prep)
 {
-       struct ceph_crypto_key *ckey = prep->payload[0];
+       struct ceph_crypto_key *ckey = prep->payload.data[0];
        ceph_crypto_key_destroy(ckey);
        kfree(ckey);
 }
 
 static void ceph_key_destroy(struct key *key)
 {
-       struct ceph_crypto_key *ckey = key->payload.data;
+       struct ceph_crypto_key *ckey = key->payload.data[0];
 
        ceph_crypto_key_destroy(ckey);
        kfree(ckey);
index 31cd4fd754869b8e621f0c5ecbfa5bca855684a7..c79b85eb4d4ca4712465b6bbeda7ed74d2624344 100644 (file)
@@ -122,7 +122,7 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
                                        goto bad_option_value;
 
                                kdebug("dns error no. = %lu", derrno);
-                               prep->type_data[0] = ERR_PTR(-derrno);
+                               prep->payload.data[dns_key_error] = ERR_PTR(-derrno);
                                continue;
                        }
 
@@ -137,8 +137,8 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
 
        /* don't cache the result if we're caching an error saying there's no
         * result */
-       if (prep->type_data[0]) {
-               kleave(" = 0 [h_error %ld]", PTR_ERR(prep->type_data[0]));
+       if (prep->payload.data[dns_key_error]) {
+               kleave(" = 0 [h_error %ld]", PTR_ERR(prep->payload.data[dns_key_error]));
                return 0;
        }
 
@@ -155,7 +155,7 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
        memcpy(upayload->data, data, result_len);
        upayload->data[result_len] = '\0';
 
-       prep->payload[0] = upayload;
+       prep->payload.data[dns_key_data] = upayload;
        kleave(" = 0");
        return 0;
 }
@@ -167,7 +167,7 @@ static void dns_resolver_free_preparse(struct key_preparsed_payload *prep)
 {
        pr_devel("==>%s()\n", __func__);
 
-       kfree(prep->payload[0]);
+       kfree(prep->payload.data[dns_key_data]);
 }
 
 /*
@@ -223,10 +223,10 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data)
  */
 static void dns_resolver_describe(const struct key *key, struct seq_file *m)
 {
-       int err = key->type_data.x[0];
-
        seq_puts(m, key->description);
        if (key_is_instantiated(key)) {
+               int err = PTR_ERR(key->payload.data[dns_key_error]);
+
                if (err)
                        seq_printf(m, ": %d", err);
                else
@@ -241,8 +241,10 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m)
 static long dns_resolver_read(const struct key *key,
                              char __user *buffer, size_t buflen)
 {
-       if (key->type_data.x[0])
-               return key->type_data.x[0];
+       int err = PTR_ERR(key->payload.data[dns_key_error]);
+
+       if (err)
+               return err;
 
        return user_read(key, buffer, buflen);
 }
index 39d2c39bdf872713e890792914597f29a4ef53ae..4677b6fa6dda2c71ace9d97536a450684d18d3ef 100644 (file)
@@ -70,7 +70,7 @@ int dns_query(const char *type, const char *name, size_t namelen,
              const char *options, char **_result, time_t *_expiry)
 {
        struct key *rkey;
-       struct user_key_payload *upayload;
+       const struct user_key_payload *upayload;
        const struct cred *saved_cred;
        size_t typelen, desclen;
        char *desc, *cp;
@@ -137,12 +137,11 @@ int dns_query(const char *type, const char *name, size_t namelen,
                goto put;
 
        /* If the DNS server gave an error, return that to the caller */
-       ret = rkey->type_data.x[0];
+       ret = PTR_ERR(rkey->payload.data[dns_key_error]);
        if (ret)
                goto put;
 
-       upayload = rcu_dereference_protected(rkey->payload.data,
-                                            lockdep_is_held(&rkey->sem));
+       upayload = user_key_payload(rkey);
        len = upayload->datalen;
 
        ret = -ENOMEM;
index 7af1ed39c0091de232f5b487ac557ba76e3e9b59..0c570d40e4d63283c25b9fb5c51b8879765b4aae 100644 (file)
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
+/*
+ * Layout of key payload words.
+ */
+enum {
+       dns_key_data,
+       dns_key_error,
+};
+
 /*
  * dns_key.c
  */
index 25d60ed15284a56b1a2f6b9bc8c680f0c9f567c0..1f8a144a5dc2c7b15a2f7f9724758b38ab4146d9 100644 (file)
@@ -305,7 +305,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
 
        if (!key)
                key = rx->key;
-       if (key && !key->payload.data)
+       if (key && !key->payload.data[0])
                key = NULL; /* a no-security key */
 
        bundle = rxrpc_get_bundle(rx, trans, key, service_id, gfp);
index db0f39f5ef96dcff51e10f09f6eebf4490be8d1e..da3cc09f683e982a43269d166acfad0e05575020 100644 (file)
@@ -148,10 +148,10 @@ static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
                       token->kad->ticket[6], token->kad->ticket[7]);
 
        /* count the number of tokens attached */
-       prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1);
+       prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
 
        /* attach the data */
-       for (pptoken = (struct rxrpc_key_token **)&prep->payload[0];
+       for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
             *pptoken;
             pptoken = &(*pptoken)->next)
                continue;
@@ -522,7 +522,7 @@ static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep,
                goto inval;
 
        /* attach the payload */
-       for (pptoken = (struct rxrpc_key_token **)&prep->payload[0];
+       for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
             *pptoken;
             pptoken = &(*pptoken)->next)
                continue;
@@ -764,10 +764,10 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep)
        memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
 
        /* count the number of tokens attached */
-       prep->type_data[0] = (void *)((unsigned long)prep->type_data[0] + 1);
+       prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
 
        /* attach the data */
-       pp = (struct rxrpc_key_token **)&prep->payload[0];
+       pp = (struct rxrpc_key_token **)&prep->payload.data[0];
        while (*pp)
                pp = &(*pp)->next;
        *pp = token;
@@ -814,7 +814,7 @@ static void rxrpc_free_token_list(struct rxrpc_key_token *token)
  */
 static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
 {
-       rxrpc_free_token_list(prep->payload[0]);
+       rxrpc_free_token_list(prep->payload.data[0]);
 }
 
 /*
@@ -831,7 +831,7 @@ static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
        if (prep->datalen != 8)
                return -EINVAL;
 
-       memcpy(&prep->type_data, prep->data, 8);
+       memcpy(&prep->payload.data[2], prep->data, 8);
 
        ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(ci)) {
@@ -842,7 +842,7 @@ static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
        if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
                BUG();
 
-       prep->payload[0] = ci;
+       prep->payload.data[0] = ci;
        _leave(" = 0");
        return 0;
 }
@@ -852,8 +852,8 @@ static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
  */
 static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
 {
-       if (prep->payload[0])
-               crypto_free_blkcipher(prep->payload[0]);
+       if (prep->payload.data[0])
+               crypto_free_blkcipher(prep->payload.data[0]);
 }
 
 /*
@@ -861,7 +861,7 @@ static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
  */
 static void rxrpc_destroy(struct key *key)
 {
-       rxrpc_free_token_list(key->payload.data);
+       rxrpc_free_token_list(key->payload.data[0]);
 }
 
 /*
@@ -869,9 +869,9 @@ static void rxrpc_destroy(struct key *key)
  */
 static void rxrpc_destroy_s(struct key *key)
 {
-       if (key->payload.data) {
-               crypto_free_blkcipher(key->payload.data);
-               key->payload.data = NULL;
+       if (key->payload.data[0]) {
+               crypto_free_blkcipher(key->payload.data[0]);
+               key->payload.data[0] = NULL;
        }
 }
 
@@ -1070,7 +1070,7 @@ static long rxrpc_read(const struct key *key,
        size += 1 * 4;  /* token count */
 
        ntoks = 0;
-       for (token = key->payload.data; token; token = token->next) {
+       for (token = key->payload.data[0]; token; token = token->next) {
                toksize = 4;    /* sec index */
 
                switch (token->security_index) {
@@ -1163,7 +1163,7 @@ static long rxrpc_read(const struct key *key,
        ENCODE(ntoks);
 
        tok = 0;
-       for (token = key->payload.data; token; token = token->next) {
+       for (token = key->payload.data[0]; token; token = token->next) {
                toksize = toksizes[tok++];
                ENCODE(toksize);
                oldxdr = xdr;
index c0042807bfc6a5e2b6e03d70fbcffe097be73326..a40d3afe93b7f3ee657985753c320210815f62a9 100644 (file)
@@ -158,7 +158,7 @@ int rxrpc_client_sendmsg(struct rxrpc_sock *rx, struct rxrpc_transport *trans,
                        service_id = htons(srx->srx_service);
                }
                key = rx->key;
-               if (key && !rx->key->payload.data)
+               if (key && !rx->key->payload.data[0])
                        key = NULL;
                bundle = rxrpc_get_bundle(rx, trans, key, service_id,
                                          GFP_KERNEL);
index 49b3cc31ee1f505b65bf21f6042e6727e2d2ed93..8334474eb26c773664ae56bc8c064e9aa9249b45 100644 (file)
@@ -137,9 +137,9 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
        if (ret < 0)
                return ret;
 
-       if (!key->payload.data)
+       token = key->payload.data[0];
+       if (!token)
                return -EKEYREJECTED;
-       token = key->payload.data;
 
        sec = rxrpc_security_lookup(token->security_index);
        if (!sec)
index f226709ebd8f159b4fef700307728accb4d2bf66..d7a9ab5a9d9ce8c95d60b5230c476e41740db607 100644 (file)
@@ -67,7 +67,7 @@ static int rxkad_init_connection_security(struct rxrpc_connection *conn)
 
        _enter("{%d},{%x}", conn->debug_id, key_serial(conn->key));
 
-       token = conn->key->payload.data;
+       token = conn->key->payload.data[0];
        conn->security_ix = token->security_index;
 
        ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
@@ -125,7 +125,7 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
        if (!conn->key)
                return;
 
-       token = conn->key->payload.data;
+       token = conn->key->payload.data[0];
        memcpy(&iv, token->kad->session_key, sizeof(iv));
 
        desc.tfm = conn->cipher;
@@ -221,7 +221,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
        rxkhdr.checksum = 0;
 
        /* encrypt from the session key */
-       token = call->conn->key->payload.data;
+       token = call->conn->key->payload.data[0];
        memcpy(&iv, token->kad->session_key, sizeof(iv));
        desc.tfm = call->conn->cipher;
        desc.info = iv.x;
@@ -433,7 +433,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
        skb_to_sgvec(skb, sg, 0, skb->len);
 
        /* decrypt from the session key */
-       token = call->conn->key->payload.data;
+       token = call->conn->key->payload.data[0];
        memcpy(&iv, token->kad->session_key, sizeof(iv));
        desc.tfm = call->conn->cipher;
        desc.info = iv.x;
@@ -780,7 +780,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
        if (conn->security_level < min_level)
                goto protocol_error;
 
-       token = conn->key->payload.data;
+       token = conn->key->payload.data[0];
 
        /* build the response packet */
        memset(&resp, 0, sizeof(resp));
@@ -848,12 +848,12 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
                }
        }
 
-       ASSERT(conn->server_key->payload.data != NULL);
+       ASSERT(conn->server_key->payload.data[0] != NULL);
        ASSERTCMP((unsigned long) ticket & 7UL, ==, 0);
 
-       memcpy(&iv, &conn->server_key->type_data, sizeof(iv));
+       memcpy(&iv, &conn->server_key->payload.data[2], sizeof(iv));
 
-       desc.tfm = conn->server_key->payload.data;
+       desc.tfm = conn->server_key->payload.data[0];
        desc.info = iv.x;
        desc.flags = 0;
 
index 159ef3ea41308dbb2ef44e2c491d44083c27d72f..461f8d89157948510fda91e3286eab12d2e456ab 100644 (file)
@@ -247,7 +247,7 @@ int evm_init_key(void)
                return -ENOENT;
 
        down_read(&evm_key->sem);
-       ekp = evm_key->payload.data;
+       ekp = evm_key->payload.data[0];
        if (ekp->decrypted_datalen > MAX_KEY_SIZE) {
                rc = -EINVAL;
                goto out;
index b6adb94f6d52573aecf2e38a16724e06895dded6..907c1522ee469b05d42bcf9a839c0a80bf7eff6c 100644 (file)
 
 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;
        }
 
index 7bed4ad7cd764a9fb9560282da63d93eeab6076b..927db9f35ad6f1bddeb51169e84c1bb526f85f21 100644 (file)
@@ -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 = {
index 8136a2d44c63ddb3a76f30f35b6780ff19b74ae9..47802c0de73567015743e26bebc4af71b3638a02 100644 (file)
@@ -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);
index 013f7e5d3a2fce42d026fd87a4a0d6e94af1d53f..b5b4812dbc87bbaba9f2c00812ca770d82a9bd29 100644 (file)
@@ -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:
index c0478465d1ac2db54c90563ea3a09d35836fa86e..ab7997ded7255258365169abaf820e811e0a7768 100644 (file)
@@ -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;
index 6110fa498494af097b38fbe5202cb55150340d15..fb111eafcb893e4f5146c74a84f8499d4e1553c4 100644 (file)
@@ -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;
 
index d33437007ad229313a5ef483826e427a74350876..f931ccfeefb01b34b7067caa2fe58774d0274edc 100644 (file)
@@ -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;
index 43b4cddbf2b39ebd838e3849a1e59e9c7c22c945..a3f85d2a00bb469391fc9a9a504c949e653d4a16 100644 (file)
@@ -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);
                }
index 486ef6fa393b2cc9d8ceb8cb11f187f97730bd90..95d5cfc172c624a6c2ffec7f8d77a7832bca2173 100644 (file)
@@ -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);
 }
index 5d672f7580dd5330516dd62f7d705cac46c319fb..4f0f112fe276fd7da1714e65113753394b5453e0 100644 (file)
@@ -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;
 
index d3633cf17c7d32bf3eed5c8d794963efdad63c65..903dace648a1731b2afbb2dc8b40b8169a05aba2 100644 (file)
@@ -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 = {
index 36b47bbd3d8cc277de55e0c0cdd722618ca13231..28cb30f80256911cf9ee41631659b9e8f5a6b5dd 100644 (file)
@@ -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 */