diff options
author | Theodore Ts'o <tytso@mit.edu> | 2015-05-31 19:35:32 +0200 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2015-05-31 19:35:32 +0200 |
commit | 4d3c4e5b8cae3bb45ba933a22670504239958aa1 (patch) | |
tree | 810780fe18d77d514578323183221ebbc1ced2c3 /fs/ext4/crypto_fname.c | |
parent | ext4 crypto: clean up error handling in ext4_fname_setup_filename (diff) | |
download | linux-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.c | 25 |
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; |