forked from Minki/linux
[PATCH] eCryptfs: Reduce stack usage in ecryptfs_generate_key_packet_set()
eCryptfs is gobbling a lot of stack in ecryptfs_generate_key_packet_set() because it allocates a temporary memory-hungry ecryptfs_key_record struct. This patch introduces a new kmem_cache for that struct and converts ecryptfs_generate_key_packet_set() to use it. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
29dbb3fc80
commit
eb95e7ffa5
@ -467,6 +467,7 @@ extern struct kmem_cache *ecryptfs_header_cache_1;
|
|||||||
extern struct kmem_cache *ecryptfs_header_cache_2;
|
extern struct kmem_cache *ecryptfs_header_cache_2;
|
||||||
extern struct kmem_cache *ecryptfs_xattr_cache;
|
extern struct kmem_cache *ecryptfs_xattr_cache;
|
||||||
extern struct kmem_cache *ecryptfs_lower_page_cache;
|
extern struct kmem_cache *ecryptfs_lower_page_cache;
|
||||||
|
extern struct kmem_cache *ecryptfs_key_record_cache;
|
||||||
|
|
||||||
int ecryptfs_interpose(struct dentry *hidden_dentry,
|
int ecryptfs_interpose(struct dentry *hidden_dentry,
|
||||||
struct dentry *this_dentry, struct super_block *sb,
|
struct dentry *this_dentry, struct super_block *sb,
|
||||||
|
@ -1638,6 +1638,8 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct kmem_cache *ecryptfs_key_record_cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ecryptfs_generate_key_packet_set
|
* ecryptfs_generate_key_packet_set
|
||||||
* @dest: Virtual address from which to write the key record set
|
* @dest: Virtual address from which to write the key record set
|
||||||
@ -1664,50 +1666,55 @@ ecryptfs_generate_key_packet_set(char *dest_base,
|
|||||||
&ecryptfs_superblock_to_private(
|
&ecryptfs_superblock_to_private(
|
||||||
ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
||||||
size_t written;
|
size_t written;
|
||||||
struct ecryptfs_key_record key_rec;
|
struct ecryptfs_key_record *key_rec;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
(*len) = 0;
|
(*len) = 0;
|
||||||
|
key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL);
|
||||||
|
if (!key_rec) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (mount_crypt_stat->global_auth_tok) {
|
if (mount_crypt_stat->global_auth_tok) {
|
||||||
auth_tok = mount_crypt_stat->global_auth_tok;
|
auth_tok = mount_crypt_stat->global_auth_tok;
|
||||||
if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
|
if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
|
||||||
rc = write_tag_3_packet((dest_base + (*len)),
|
rc = write_tag_3_packet((dest_base + (*len)),
|
||||||
max, auth_tok,
|
max, auth_tok,
|
||||||
crypt_stat, &key_rec,
|
crypt_stat, key_rec,
|
||||||
&written);
|
&written);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
ecryptfs_printk(KERN_WARNING, "Error "
|
ecryptfs_printk(KERN_WARNING, "Error "
|
||||||
"writing tag 3 packet\n");
|
"writing tag 3 packet\n");
|
||||||
goto out;
|
goto out_free;
|
||||||
}
|
}
|
||||||
(*len) += written;
|
(*len) += written;
|
||||||
/* Write auth tok signature packet */
|
/* Write auth tok signature packet */
|
||||||
rc = write_tag_11_packet(
|
rc = write_tag_11_packet(
|
||||||
(dest_base + (*len)),
|
(dest_base + (*len)),
|
||||||
(max - (*len)),
|
(max - (*len)),
|
||||||
key_rec.sig, ECRYPTFS_SIG_SIZE, &written);
|
key_rec->sig, ECRYPTFS_SIG_SIZE, &written);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
ecryptfs_printk(KERN_ERR, "Error writing "
|
ecryptfs_printk(KERN_ERR, "Error writing "
|
||||||
"auth tok signature packet\n");
|
"auth tok signature packet\n");
|
||||||
goto out;
|
goto out_free;
|
||||||
}
|
}
|
||||||
(*len) += written;
|
(*len) += written;
|
||||||
} else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
|
} else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
|
||||||
rc = write_tag_1_packet(dest_base + (*len),
|
rc = write_tag_1_packet(dest_base + (*len),
|
||||||
max, auth_tok,
|
max, auth_tok,
|
||||||
crypt_stat,mount_crypt_stat,
|
crypt_stat,mount_crypt_stat,
|
||||||
&key_rec, &written);
|
key_rec, &written);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
ecryptfs_printk(KERN_WARNING, "Error "
|
ecryptfs_printk(KERN_WARNING, "Error "
|
||||||
"writing tag 1 packet\n");
|
"writing tag 1 packet\n");
|
||||||
goto out;
|
goto out_free;
|
||||||
}
|
}
|
||||||
(*len) += written;
|
(*len) += written;
|
||||||
} else {
|
} else {
|
||||||
ecryptfs_printk(KERN_WARNING, "Unsupported "
|
ecryptfs_printk(KERN_WARNING, "Unsupported "
|
||||||
"authentication token type\n");
|
"authentication token type\n");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto out;
|
goto out_free;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
BUG();
|
BUG();
|
||||||
@ -1717,6 +1724,9 @@ ecryptfs_generate_key_packet_set(char *dest_base,
|
|||||||
ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");
|
ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");
|
||||||
rc = -EIO;
|
rc = -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
kmem_cache_free(ecryptfs_key_record_cache, key_rec);
|
||||||
out:
|
out:
|
||||||
if (rc)
|
if (rc)
|
||||||
(*len) = 0;
|
(*len) = 0;
|
||||||
|
@ -651,6 +651,11 @@ static struct ecryptfs_cache_info {
|
|||||||
.name = "ecryptfs_lower_page_cache",
|
.name = "ecryptfs_lower_page_cache",
|
||||||
.size = PAGE_CACHE_SIZE,
|
.size = PAGE_CACHE_SIZE,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.cache = &ecryptfs_key_record_cache,
|
||||||
|
.name = "ecryptfs_key_record_cache",
|
||||||
|
.size = sizeof(struct ecryptfs_key_record),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ecryptfs_free_kmem_caches(void)
|
static void ecryptfs_free_kmem_caches(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user