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: David Howells <dhowells@redhat.com> Acked-by: Steve Dickson <steved@redhat.com>
This commit is contained in:
parent
8a7a3eb4dd
commit
002edaf76f
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
extern struct key_type key_type_big_key;
|
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_revoke(struct key *key);
|
||||||
extern void big_key_destroy(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);
|
extern void big_key_describe(const struct key *big_key, struct seq_file *m);
|
||||||
|
|
|
@ -34,7 +34,9 @@ MODULE_LICENSE("GPL");
|
||||||
struct key_type key_type_big_key = {
|
struct key_type key_type_big_key = {
|
||||||
.name = "big_key",
|
.name = "big_key",
|
||||||
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
.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,
|
.match = user_match,
|
||||||
.revoke = big_key_revoke,
|
.revoke = big_key_revoke,
|
||||||
.destroy = big_key_destroy,
|
.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;
|
struct file *file;
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
size_t datalen = prep->datalen;
|
size_t datalen = prep->datalen;
|
||||||
|
@ -58,11 +60,9 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Set an arbitrary quota */
|
/* Set an arbitrary quota */
|
||||||
ret = key_payload_reserve(key, 16);
|
prep->quotalen = 16;
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
key->type_data.x[1] = datalen;
|
prep->type_data[1] = (void *)(unsigned long)datalen;
|
||||||
|
|
||||||
if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||||
/* Create a shmem file to store the data in. This will permit the data
|
/* 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);
|
file = shmem_kernel_file_setup("", datalen, 0);
|
||||||
if (IS_ERR(file)) {
|
if (IS_ERR(file)) {
|
||||||
ret = PTR_ERR(file);
|
ret = PTR_ERR(file);
|
||||||
goto err_quota;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
written = kernel_write(file, prep->data, prep->datalen, 0);
|
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 {
|
} else {
|
||||||
/* Just store the data in a buffer */
|
/* Just store the data in a buffer */
|
||||||
void *data = kmalloc(datalen, GFP_KERNEL);
|
void *data = kmalloc(datalen, GFP_KERNEL);
|
||||||
if (!data) {
|
if (!data)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto err_quota;
|
|
||||||
}
|
|
||||||
|
|
||||||
key->payload.data = memcpy(data, prep->data, prep->datalen);
|
prep->payload[0] = memcpy(data, prep->data, prep->datalen);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_fput:
|
err_fput:
|
||||||
fput(file);
|
fput(file);
|
||||||
err_quota:
|
|
||||||
key_payload_reserve(key, 0);
|
|
||||||
error:
|
error:
|
||||||
return ret;
|
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
|
* dispose of the links from a revoked keyring
|
||||||
* - called with the key sem write-locked
|
* - called with the key sem write-locked
|
||||||
|
|
Loading…
Reference in New Issue