diff options
| -rw-r--r-- | fs/ecryptfs/crypto.c | 68 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 6 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 9 | ||||
| -rw-r--r-- | fs/ecryptfs/super.c | 14 |
4 files changed, 83 insertions, 14 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 | } | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index a2362df58ae8..867b64c5d84f 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -162,6 +162,10 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
| 162 | #define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */ | 162 | #define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */ |
| 163 | #define MD5_DIGEST_SIZE 16 | 163 | #define MD5_DIGEST_SIZE 16 |
| 164 | #define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE | 164 | #define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE |
| 165 | #define ECRYPTFS_TAG_70_MIN_METADATA_SIZE (1 + ECRYPTFS_MIN_PKT_LEN_SIZE \ | ||
| 166 | + ECRYPTFS_SIG_SIZE + 1 + 1) | ||
| 167 | #define ECRYPTFS_TAG_70_MAX_METADATA_SIZE (1 + ECRYPTFS_MAX_PKT_LEN_SIZE \ | ||
| 168 | + ECRYPTFS_SIG_SIZE + 1 + 1) | ||
| 165 | #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED." | 169 | #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED." |
| 166 | #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE 23 | 170 | #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE 23 |
| 167 | #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FNEK_ENCRYPTED." | 171 | #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FNEK_ENCRYPTED." |
| @@ -701,6 +705,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | |||
| 701 | size_t *packet_size, | 705 | size_t *packet_size, |
| 702 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 706 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 703 | char *data, size_t max_packet_size); | 707 | char *data, size_t max_packet_size); |
| 708 | int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, | ||
| 709 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat); | ||
| 704 | int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, | 710 | int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, |
| 705 | loff_t offset); | 711 | loff_t offset); |
| 706 | 712 | ||
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 8e3b943e330f..2333203a120b 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
| @@ -679,10 +679,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | |||
| 679 | * Octets N3-N4: Block-aligned encrypted filename | 679 | * Octets N3-N4: Block-aligned encrypted filename |
| 680 | * - Consists of a minimum number of random characters, a \0 | 680 | * - Consists of a minimum number of random characters, a \0 |
| 681 | * separator, and then the filename */ | 681 | * separator, and then the filename */ |
| 682 | s->max_packet_size = (1 /* Tag 70 identifier */ | 682 | s->max_packet_size = (ECRYPTFS_TAG_70_MAX_METADATA_SIZE |
| 683 | + 3 /* Max Tag 70 packet size */ | ||
| 684 | + ECRYPTFS_SIG_SIZE /* FNEK sig */ | ||
| 685 | + 1 /* Cipher identifier */ | ||
| 686 | + s->block_aligned_filename_size); | 683 | + s->block_aligned_filename_size); |
| 687 | if (dest == NULL) { | 684 | if (dest == NULL) { |
| 688 | (*packet_size) = s->max_packet_size; | 685 | (*packet_size) = s->max_packet_size; |
| @@ -934,10 +931,10 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | |||
| 934 | goto out; | 931 | goto out; |
| 935 | } | 932 | } |
| 936 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 933 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
| 937 | if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) { | 934 | if (max_packet_size < ECRYPTFS_TAG_70_MIN_METADATA_SIZE) { |
| 938 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " | 935 | printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " |
| 939 | "at least [%d]\n", __func__, max_packet_size, | 936 | "at least [%d]\n", __func__, max_packet_size, |
| 940 | (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)); | 937 | ECRYPTFS_TAG_70_MIN_METADATA_SIZE); |
| 941 | rc = -EINVAL; | 938 | rc = -EINVAL; |
| 942 | goto out; | 939 | goto out; |
| 943 | } | 940 | } |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 9df7fd6e0c39..cf152823bbf4 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
| 31 | #include <linux/file.h> | 31 | #include <linux/file.h> |
| 32 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
| 33 | #include <linux/statfs.h> | ||
| 34 | #include <linux/magic.h> | ||
| 33 | #include "ecryptfs_kernel.h" | 35 | #include "ecryptfs_kernel.h" |
| 34 | 36 | ||
| 35 | struct kmem_cache *ecryptfs_inode_info_cache; | 37 | struct kmem_cache *ecryptfs_inode_info_cache; |
| @@ -102,10 +104,20 @@ static void ecryptfs_destroy_inode(struct inode *inode) | |||
| 102 | static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 104 | static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
| 103 | { | 105 | { |
| 104 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 106 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
| 107 | int rc; | ||
| 105 | 108 | ||
| 106 | if (!lower_dentry->d_sb->s_op->statfs) | 109 | if (!lower_dentry->d_sb->s_op->statfs) |
| 107 | return -ENOSYS; | 110 | return -ENOSYS; |
| 108 | return lower_dentry->d_sb->s_op->statfs(lower_dentry, buf); | 111 | |
| 112 | rc = lower_dentry->d_sb->s_op->statfs(lower_dentry, buf); | ||
| 113 | if (rc) | ||
| 114 | return rc; | ||
| 115 | |||
| 116 | buf->f_type = ECRYPTFS_SUPER_MAGIC; | ||
| 117 | rc = ecryptfs_set_f_namelen(&buf->f_namelen, buf->f_namelen, | ||
| 118 | &ecryptfs_superblock_to_private(dentry->d_sb)->mount_crypt_stat); | ||
| 119 | |||
| 120 | return rc; | ||
| 109 | } | 121 | } |
| 110 | 122 | ||
| 111 | /** | 123 | /** |
