Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 002edaf7 authored by David Howells's avatar David Howells
Browse files

KEYS: big_key: Use key preparsing



Make use of key preparsing in the big key type so that quota size determination
can take place prior to keyring locking when a key is being added.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarSteve Dickson <steved@redhat.com>
parent 8a7a3eb4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@

extern struct key_type key_type_big_key;

extern int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep);
extern int big_key_preparse(struct key_preparsed_payload *prep);
extern void big_key_free_preparse(struct key_preparsed_payload *prep);
extern void big_key_revoke(struct key *key);
extern void big_key_destroy(struct key *key);
extern void big_key_describe(const struct key *big_key, struct seq_file *m);
+25 −16
Original line number Diff line number Diff line
@@ -34,7 +34,9 @@ MODULE_LICENSE("GPL");
struct key_type key_type_big_key = {
	.name			= "big_key",
	.def_lookup_type	= KEYRING_SEARCH_LOOKUP_DIRECT,
	.instantiate		= big_key_instantiate,
	.preparse		= big_key_preparse,
	.free_preparse		= big_key_free_preparse,
	.instantiate		= generic_key_instantiate,
	.match			= user_match,
	.revoke			= big_key_revoke,
	.destroy		= big_key_destroy,
@@ -43,11 +45,11 @@ struct key_type key_type_big_key = {
};

/*
 * Instantiate a big key
 * Preparse a big key
 */
int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
int big_key_preparse(struct key_preparsed_payload *prep)
{
	struct path *path = (struct path *)&key->payload.data2;
	struct path *path = (struct path *)&prep->payload;
	struct file *file;
	ssize_t written;
	size_t datalen = prep->datalen;
@@ -58,11 +60,9 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
		goto error;

	/* Set an arbitrary quota */
	ret = key_payload_reserve(key, 16);
	if (ret < 0)
		goto error;
	prep->quotalen = 16;

	key->type_data.x[1] = datalen;
	prep->type_data[1] = (void *)(unsigned long)datalen;

	if (datalen > BIG_KEY_FILE_THRESHOLD) {
		/* Create a shmem file to store the data in.  This will permit the data
@@ -73,7 +73,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
		file = shmem_kernel_file_setup("", datalen, 0);
		if (IS_ERR(file)) {
			ret = PTR_ERR(file);
			goto err_quota;
			goto error;
		}

		written = kernel_write(file, prep->data, prep->datalen, 0);
@@ -93,23 +93,32 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
	} else {
		/* Just store the data in a buffer */
		void *data = kmalloc(datalen, GFP_KERNEL);
		if (!data) {
			ret = -ENOMEM;
			goto err_quota;
		}
		if (!data)
			return -ENOMEM;

		key->payload.data = memcpy(data, prep->data, prep->datalen);
		prep->payload[0] = memcpy(data, prep->data, prep->datalen);
	}
	return 0;

err_fput:
	fput(file);
err_quota:
	key_payload_reserve(key, 0);
error:
	return ret;
}

/*
 * Clear preparsement.
 */
void big_key_free_preparse(struct key_preparsed_payload *prep)
{
	if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
		struct path *path = (struct path *)&prep->payload;
		path_put(path);
	} else {
		kfree(prep->payload[0]);
	}
}

/*
 * dispose of the links from a revoked keyring
 * - called with the key sem write-locked