summaryrefslogtreecommitdiffstats
path: root/fs/ext4/crypto_fname.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2015-05-31 19:35:32 +0200
committerTheodore Ts'o <tytso@mit.edu>2015-05-31 19:35:32 +0200
commit4d3c4e5b8cae3bb45ba933a22670504239958aa1 (patch)
tree810780fe18d77d514578323183221ebbc1ced2c3 /fs/ext4/crypto_fname.c
parentext4 crypto: clean up error handling in ext4_fname_setup_filename (diff)
downloadlinux-4d3c4e5b8cae3bb45ba933a22670504239958aa1.tar.xz
linux-4d3c4e5b8cae3bb45ba933a22670504239958aa1.zip
ext4 crypto: allocate the right amount of memory for the on-disk symlink
Previously we were taking the required padding when allocating space for the on-disk symlink. This caused a buffer overrun which could trigger a krenel crash when running fsstress. Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/crypto_fname.c')
-rw-r--r--fs/ext4/crypto_fname.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
index 23af41f73e90..7dc4eb55913c 100644
--- a/fs/ext4/crypto_fname.c
+++ b/fs/ext4/crypto_fname.c
@@ -262,8 +262,20 @@ u32 ext4_fname_crypto_round_up(u32 size, u32 blksize)
return ((size+blksize-1)/blksize)*blksize;
}
-/**
- * ext4_fname_crypto_alloc_obuff() -
+unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen)
+{
+ struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
+ int padding = 32;
+
+ if (ci)
+ padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
+ if (ilen < EXT4_CRYPTO_BLOCK_SIZE)
+ ilen = EXT4_CRYPTO_BLOCK_SIZE;
+ return ext4_fname_crypto_round_up(ilen, padding);
+}
+
+/*
+ * ext4_fname_crypto_alloc_buffer() -
*
* Allocates an output buffer that is sufficient for the crypto operation
* specified by the context and the direction.
@@ -271,15 +283,8 @@ u32 ext4_fname_crypto_round_up(u32 size, u32 blksize)
int ext4_fname_crypto_alloc_buffer(struct inode *inode,
u32 ilen, struct ext4_str *crypto_str)
{
- unsigned int olen;
- int padding = 16;
- struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
+ unsigned int olen = ext4_fname_encrypted_size(inode, ilen);
- if (ci)
- padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
- if (padding < EXT4_CRYPTO_BLOCK_SIZE)
- padding = EXT4_CRYPTO_BLOCK_SIZE;
- olen = ext4_fname_crypto_round_up(ilen, padding);
crypto_str->len = olen;
if (olen < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2)
olen = EXT4_FNAME_CRYPTO_DIGEST_SIZE*2;