fscrypt: fix up fscrypt_fname_encrypted_size() for internal use
Filesystems don't need fscrypt_fname_encrypted_size() anymore, so
unexport it and move it to fscrypt_private.h.
We also never calculate the encrypted size of a filename without having
the fscrypt_info present since it is needed to know the amount of
NUL-padding which is determined by the encryption policy, and also we
will always truncate the NUL-padding to the maximum filename length.
Therefore, also make fscrypt_fname_encrypted_size() assume that the
fscrypt_info is present, and make it truncate the returned length to the
specified max_len.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 5bf38d9..28f9f05 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -143,12 +143,12 @@ int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
* counting it (even though it is meaningless for ciphertext) is simpler
* for now since filesystems will assume it is there and subtract it.
*/
- if (sizeof(struct fscrypt_symlink_data) + len > max_len)
+ if (!fscrypt_fname_encrypted_size(dir, len,
+ max_len - sizeof(struct fscrypt_symlink_data),
+ &disk_link->len))
return -ENAMETOOLONG;
- disk_link->len = min_t(unsigned int,
- sizeof(struct fscrypt_symlink_data) +
- fscrypt_fname_encrypted_size(dir, len),
- max_len);
+ disk_link->len += sizeof(struct fscrypt_symlink_data);
+
disk_link->name = NULL;
return 0;
}