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:
@@ -20,6 +20,16 @@
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
* Layout of key payload words.
|
||||
*/
|
||||
enum {
|
||||
big_key_data,
|
||||
big_key_path,
|
||||
big_key_path_2nd_part,
|
||||
big_key_len,
|
||||
};
|
||||
|
||||
/*
|
||||
* If the data is under this limit, there's no point creating a shm file to
|
||||
* hold it as the permanently resident metadata for the shmem fs will be at
|
||||
@@ -47,7 +57,7 @@ struct key_type key_type_big_key = {
|
||||
*/
|
||||
int big_key_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
struct path *path = (struct path *)&prep->payload;
|
||||
struct path *path = (struct path *)&prep->payload.data[big_key_path];
|
||||
struct file *file;
|
||||
ssize_t written;
|
||||
size_t datalen = prep->datalen;
|
||||
@@ -60,7 +70,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
|
||||
/* Set an arbitrary quota */
|
||||
prep->quotalen = 16;
|
||||
|
||||
prep->type_data[1] = (void *)(unsigned long)datalen;
|
||||
prep->payload.data[big_key_len] = (void *)(unsigned long)datalen;
|
||||
|
||||
if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||
/* Create a shmem file to store the data in. This will permit the data
|
||||
@@ -94,7 +104,8 @@ int big_key_preparse(struct key_preparsed_payload *prep)
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
prep->payload[0] = memcpy(data, prep->data, prep->datalen);
|
||||
prep->payload.data[big_key_data] = data;
|
||||
memcpy(data, prep->data, prep->datalen);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -110,10 +121,10 @@ error:
|
||||
void big_key_free_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||
struct path *path = (struct path *)&prep->payload;
|
||||
struct path *path = (struct path *)&prep->payload.data[big_key_path];
|
||||
path_put(path);
|
||||
} else {
|
||||
kfree(prep->payload[0]);
|
||||
kfree(prep->payload.data[big_key_data]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,11 +134,12 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
|
||||
*/
|
||||
void big_key_revoke(struct key *key)
|
||||
{
|
||||
struct path *path = (struct path *)&key->payload.data2;
|
||||
struct path *path = (struct path *)&key->payload.data[big_key_path];
|
||||
|
||||
/* clear the quota */
|
||||
key_payload_reserve(key, 0);
|
||||
if (key_is_instantiated(key) && key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD)
|
||||
if (key_is_instantiated(key) &&
|
||||
(size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
|
||||
vfs_truncate(path, 0);
|
||||
}
|
||||
|
||||
@@ -136,14 +148,16 @@ void big_key_revoke(struct key *key)
|
||||
*/
|
||||
void big_key_destroy(struct key *key)
|
||||
{
|
||||
if (key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) {
|
||||
struct path *path = (struct path *)&key->payload.data2;
|
||||
size_t datalen = (size_t)key->payload.data[big_key_len];
|
||||
|
||||
if (datalen) {
|
||||
struct path *path = (struct path *)&key->payload.data[big_key_path];
|
||||
path_put(path);
|
||||
path->mnt = NULL;
|
||||
path->dentry = NULL;
|
||||
} else {
|
||||
kfree(key->payload.data);
|
||||
key->payload.data = NULL;
|
||||
kfree(key->payload.data[big_key_data]);
|
||||
key->payload.data[big_key_data] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,12 +166,12 @@ void big_key_destroy(struct key *key)
|
||||
*/
|
||||
void big_key_describe(const struct key *key, struct seq_file *m)
|
||||
{
|
||||
unsigned long datalen = key->type_data.x[1];
|
||||
size_t datalen = (size_t)key->payload.data[big_key_len];
|
||||
|
||||
seq_puts(m, key->description);
|
||||
|
||||
if (key_is_instantiated(key))
|
||||
seq_printf(m, ": %lu [%s]",
|
||||
seq_printf(m, ": %zu [%s]",
|
||||
datalen,
|
||||
datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
|
||||
}
|
||||
@@ -168,14 +182,14 @@ void big_key_describe(const struct key *key, struct seq_file *m)
|
||||
*/
|
||||
long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
|
||||
{
|
||||
unsigned long datalen = key->type_data.x[1];
|
||||
size_t datalen = (size_t)key->payload.data[big_key_len];
|
||||
long ret;
|
||||
|
||||
if (!buffer || buflen < datalen)
|
||||
return datalen;
|
||||
|
||||
if (datalen > BIG_KEY_FILE_THRESHOLD) {
|
||||
struct path *path = (struct path *)&key->payload.data2;
|
||||
struct path *path = (struct path *)&key->payload.data[big_key_path];
|
||||
struct file *file;
|
||||
loff_t pos;
|
||||
|
||||
@@ -190,7 +204,8 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
|
||||
ret = -EIO;
|
||||
} else {
|
||||
ret = datalen;
|
||||
if (copy_to_user(buffer, key->payload.data, datalen) != 0)
|
||||
if (copy_to_user(buffer, key->payload.data[big_key_data],
|
||||
datalen) != 0)
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user