forked from mirrors/linux
		
	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 <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
This commit is contained in:
		
							parent
							
								
									4adc605edc
								
							
						
					
					
						commit
						146aa8b145
					
				
					 49 changed files with 286 additions and 230 deletions
				
			
		|  | @ -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. | ||||
|      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 ->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. | ||||
|      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 | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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]; | ||||
| } | ||||
|  |  | |||
|  | @ -307,25 +307,34 @@ static int asymmetric_key_preparse(struct key_preparsed_payload *prep) | |||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Clean up the preparse data | ||||
|  * Clean up the key ID list | ||||
|  */ | ||||
| static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) | ||||
| static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids) | ||||
| { | ||||
| 	struct asymmetric_key_subtype *subtype = prep->type_data[0]; | ||||
| 	struct asymmetric_key_ids *kids = prep->type_data[1]; | ||||
| 	int i; | ||||
| 
 | ||||
| 	pr_devel("==>%s()\n", __func__); | ||||
| 
 | ||||
| 	if (subtype) { | ||||
| 		subtype->destroy(prep->payload[0]); | ||||
| 		module_put(subtype->owner); | ||||
| 	} | ||||
| 	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->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.data[asym_crypto]); | ||||
| 		module_put(subtype->owner); | ||||
| 	} | ||||
| 	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 = { | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 @@ cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) | |||
| 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)); | ||||
| 	} | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -660,7 +660,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, | |||
| 			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 | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -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 @@ int _ext4_get_encryption_info(struct inode *inode) | |||
| 	} | ||||
| 	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; | ||||
|  |  | |||
|  | @ -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 @@ int _f2fs_get_encryption_info(struct inode *inode) | |||
| 	} | ||||
| 	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; | ||||
|  |  | |||
|  | @ -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--) { | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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 */ | ||||
|  |  | |||
|  | @ -18,6 +18,16 @@ | |||
| 
 | ||||
| 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. | ||||
|  |  | |||
|  | @ -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 */ | ||||
|  |  | |||
|  | @ -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 */ | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 @@ static int ceph_key_preparse(struct key_preparsed_payload *prep) | |||
| 
 | ||||
| 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); | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -22,6 +22,14 @@ | |||
| #include <linux/kernel.h> | ||||
| #include <linux/sched.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * Layout of key payload words. | ||||
|  */ | ||||
| enum { | ||||
| 	dns_key_data, | ||||
| 	dns_key_error, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * dns_key.c | ||||
|  */ | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 @@ int big_key_preparse(struct key_preparsed_payload *prep) | |||
| 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; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -303,10 +303,10 @@ static char *datablob_format(struct encrypted_key_payload *epayload, | |||
|  * | ||||
|  * 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 @@ static long encrypted_read(const struct key *key, char __user *buffer, | |||
|  */ | ||||
| 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 = { | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, | |||
| 			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); | ||||
| 		} | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 = { | ||||
|  |  | |||
|  | @ -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 */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 David Howells
						David Howells