diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2011-11-05 13:45:08 -0400 |
---|---|---|
committer | Tyler Hicks <tyhicks@canonical.com> | 2012-02-16 17:06:21 -0500 |
commit | 4a26620df451ad46151ad21d711ed43e963c004e (patch) | |
tree | bf035ea6a656b3e19fe93bf37991632cad96d971 /fs/ecryptfs/crypto.c | |
parent | c38e23456278e967f094b08247ffc3711b1029b2 (diff) |
eCryptfs: Improve statfs reporting
statfs() calls on eCryptfs files returned the wrong filesystem type and,
when using filename encryption, the wrong maximum filename length.
If mount-wide filename encryption is enabled, the cipher block size and
the lower filesystem's max filename length will determine the max
eCryptfs filename length. Pre-tested, known good lengths are used when
the lower filesystem's namelen is 255 and a cipher with 8 or 16 byte
block sizes is used. In other, less common cases, we fall back to a safe
rounded-down estimate when determining the eCryptfs namelen.
https://launchpad.net/bugs/885744
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reported-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'fs/ecryptfs/crypto.c')
-rw-r--r-- | fs/ecryptfs/crypto.c | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 63ab24510649..ea9931281557 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1990,6 +1990,17 @@ out: | |||
1990 | return; | 1990 | return; |
1991 | } | 1991 | } |
1992 | 1992 | ||
1993 | static size_t ecryptfs_max_decoded_size(size_t encoded_size) | ||
1994 | { | ||
1995 | /* Not exact; conservatively long. Every block of 4 | ||
1996 | * encoded characters decodes into a block of 3 | ||
1997 | * decoded characters. This segment of code provides | ||
1998 | * the caller with the maximum amount of allocated | ||
1999 | * space that @dst will need to point to in a | ||
2000 | * subsequent call. */ | ||
2001 | return ((encoded_size + 1) * 3) / 4; | ||
2002 | } | ||
2003 | |||
1993 | /** | 2004 | /** |
1994 | * ecryptfs_decode_from_filename | 2005 | * ecryptfs_decode_from_filename |
1995 | * @dst: If NULL, this function only sets @dst_size and returns. If | 2006 | * @dst: If NULL, this function only sets @dst_size and returns. If |
@@ -2008,13 +2019,7 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size, | |||
2008 | size_t dst_byte_offset = 0; | 2019 | size_t dst_byte_offset = 0; |
2009 | 2020 | ||
2010 | if (dst == NULL) { | 2021 | if (dst == NULL) { |
2011 | /* Not exact; conservatively long. Every block of 4 | 2022 | (*dst_size) = ecryptfs_max_decoded_size(src_size); |
2012 | * encoded characters decodes into a block of 3 | ||
2013 | * decoded characters. This segment of code provides | ||
2014 | * the caller with the maximum amount of allocated | ||
2015 | * space that @dst will need to point to in a | ||
2016 | * subsequent call. */ | ||
2017 | (*dst_size) = (((src_size + 1) * 3) / 4); | ||
2018 | goto out; | 2023 | goto out; |
2019 | } | 2024 | } |
2020 | while (src_byte_offset < src_size) { | 2025 | while (src_byte_offset < src_size) { |
@@ -2239,3 +2244,52 @@ out_free: | |||
2239 | out: | 2244 | out: |
2240 | return rc; | 2245 | return rc; |
2241 | } | 2246 | } |
2247 | |||
2248 | #define ENC_NAME_MAX_BLOCKLEN_8_OR_16 143 | ||
2249 | |||
2250 | int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, | ||
2251 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
2252 | { | ||
2253 | struct blkcipher_desc desc; | ||
2254 | struct mutex *tfm_mutex; | ||
2255 | size_t cipher_blocksize; | ||
2256 | int rc; | ||
2257 | |||
2258 | if (!(mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) { | ||
2259 | (*namelen) = lower_namelen; | ||
2260 | return 0; | ||
2261 | } | ||
2262 | |||
2263 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, | ||
2264 | mount_crypt_stat->global_default_fn_cipher_name); | ||
2265 | if (unlikely(rc)) { | ||
2266 | (*namelen) = 0; | ||
2267 | return rc; | ||
2268 | } | ||
2269 | |||
2270 | mutex_lock(tfm_mutex); | ||
2271 | cipher_blocksize = crypto_blkcipher_blocksize(desc.tfm); | ||
2272 | mutex_unlock(tfm_mutex); | ||
2273 | |||
2274 | /* Return an exact amount for the common cases */ | ||
2275 | if (lower_namelen == NAME_MAX | ||
2276 | && (cipher_blocksize == 8 || cipher_blocksize == 16)) { | ||
2277 | (*namelen) = ENC_NAME_MAX_BLOCKLEN_8_OR_16; | ||
2278 | return 0; | ||
2279 | } | ||
2280 | |||
2281 | /* Return a safe estimate for the uncommon cases */ | ||
2282 | (*namelen) = lower_namelen; | ||
2283 | (*namelen) -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; | ||
2284 | /* Since this is the max decoded size, subtract 1 "decoded block" len */ | ||
2285 | (*namelen) = ecryptfs_max_decoded_size(*namelen) - 3; | ||
2286 | (*namelen) -= ECRYPTFS_TAG_70_MAX_METADATA_SIZE; | ||
2287 | (*namelen) -= ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES; | ||
2288 | /* Worst case is that the filename is padded nearly a full block size */ | ||
2289 | (*namelen) -= cipher_blocksize - 1; | ||
2290 | |||
2291 | if ((*namelen) < 0) | ||
2292 | (*namelen) = 0; | ||
2293 | |||
2294 | return 0; | ||
2295 | } | ||