From: Eric Biggers Date: Sun, 15 Nov 2020 03:15:36 +0000 (-0800) Subject: fscrypt-crypt-util: fix maximum IV size X-Git-Tag: v2022.05.01~605 X-Git-Url: http://git.apps.os.sepia.ceph.com/?p=xfstests-dev.git;a=commitdiff_plain;h=609bb3562241f9fc877aff7309d62af6cb10795d;hp=0743230c36029be5f686e278cbd154ae263b44b6 fscrypt-crypt-util: fix maximum IV size In commit 65cd8e8a8e81 ("fscrypt-crypt-util: fix IV incrementing for --iv-ino-lblk-32") I mistakenly decreased the size of fscrypt_iv to 24 bytes, which is the most that is explicitly needed by any of the IV generation methods. However, Adiantum encryption takes a 32-byte IV, so the buffer still needs to be 32 bytes, with any extra bytes zeroed. So restore the size to 32 bytes. This fixes a buffer overread that caused generic/550 and generic/584 to sometimes fail, depending on the build of the fscrypt-crypt-util binary. (Most of the time it still worked by chance.) Fixes: 65cd8e8a8e81 ("fscrypt-crypt-util: fix IV incrementing for --iv-ino-lblk-32") Signed-off-by: Eric Biggers Signed-off-by: Eryu Guan --- diff --git a/src/fscrypt-crypt-util.c b/src/fscrypt-crypt-util.c index 26698d7a..03cc3c4a 100644 --- a/src/fscrypt-crypt-util.c +++ b/src/fscrypt-crypt-util.c @@ -1642,6 +1642,7 @@ static u64 siphash_1u64(const u64 key[2], u64 data) #define FILE_NONCE_SIZE 16 #define UUID_SIZE 16 #define MAX_KEY_SIZE 64 +#define MAX_IV_SIZE ADIANTUM_IV_SIZE static const struct fscrypt_cipher { const char *name; @@ -1715,6 +1716,8 @@ union fscrypt_iv { /* IV_INO_LBLK_64: inode number */ __le32 inode_number; }; + /* Any extra bytes up to the algorithm's IV size must be zeroed */ + u8 bytes[MAX_IV_SIZE]; }; static void crypt_loop(const struct fscrypt_cipher *cipher, const u8 *key, @@ -1736,9 +1739,9 @@ static void crypt_loop(const struct fscrypt_cipher *cipher, const u8 *key, memset(&buf[res], 0, crypt_len - res); if (decrypting) - cipher->decrypt(key, (u8 *)iv, buf, buf, crypt_len); + cipher->decrypt(key, iv->bytes, buf, buf, crypt_len); else - cipher->encrypt(key, (u8 *)iv, buf, buf, crypt_len); + cipher->encrypt(key, iv->bytes, buf, buf, crypt_len); full_write(STDOUT_FILENO, buf, crypt_len);