diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-20 12:08:37 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-20 12:08:37 -0400 |
| commit | 43f70c960180c11d64ee3e9e53075fe1acd43ff1 (patch) | |
| tree | 653ebe7e04fd7367904678e302b2bdd74776faaa /fs | |
| parent | 0d9cf33b4aabd8de03f80659ceae967ba2b3ba30 (diff) | |
| parent | e86281e700cca8a773f9a572fa406adf2784ba5c (diff) | |
Merge tag 'ecryptfs-4.17-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs
Pull eCryptfs fixes from Tyler Hicks:
"Minor cleanups and a bug fix to completely ignore unencrypted
filenames in the lower filesystem when filename encryption is enabled
at the eCryptfs layer"
* tag 'ecryptfs-4.17-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
eCryptfs: don't pass up plaintext names when using filename encryption
ecryptfs: fix spelling mistake: "cadidate" -> "candidate"
ecryptfs: lookup: Don't check if mount_crypt_stat is NULL
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ecryptfs/crypto.c | 41 | ||||
| -rw-r--r-- | fs/ecryptfs/file.c | 21 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 3 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 2 |
4 files changed, 46 insertions, 21 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 846ca150d52e..4dd842f72846 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -1997,6 +1997,16 @@ out: | |||
| 1997 | return rc; | 1997 | return rc; |
| 1998 | } | 1998 | } |
| 1999 | 1999 | ||
| 2000 | static bool is_dot_dotdot(const char *name, size_t name_size) | ||
| 2001 | { | ||
| 2002 | if (name_size == 1 && name[0] == '.') | ||
| 2003 | return true; | ||
| 2004 | else if (name_size == 2 && name[0] == '.' && name[1] == '.') | ||
| 2005 | return true; | ||
| 2006 | |||
| 2007 | return false; | ||
| 2008 | } | ||
| 2009 | |||
| 2000 | /** | 2010 | /** |
| 2001 | * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext | 2011 | * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext |
| 2002 | * @plaintext_name: The plaintext name | 2012 | * @plaintext_name: The plaintext name |
| @@ -2021,13 +2031,21 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, | |||
| 2021 | size_t packet_size; | 2031 | size_t packet_size; |
| 2022 | int rc = 0; | 2032 | int rc = 0; |
| 2023 | 2033 | ||
| 2024 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | 2034 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) && |
| 2025 | && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | 2035 | !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)) { |
| 2026 | && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) | 2036 | if (is_dot_dotdot(name, name_size)) { |
| 2027 | && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, | 2037 | rc = ecryptfs_copy_filename(plaintext_name, |
| 2028 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { | 2038 | plaintext_name_size, |
| 2029 | const char *orig_name = name; | 2039 | name, name_size); |
| 2030 | size_t orig_name_size = name_size; | 2040 | goto out; |
| 2041 | } | ||
| 2042 | |||
| 2043 | if (name_size <= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE || | ||
| 2044 | strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, | ||
| 2045 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)) { | ||
| 2046 | rc = -EINVAL; | ||
| 2047 | goto out; | ||
| 2048 | } | ||
| 2031 | 2049 | ||
| 2032 | name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; | 2050 | name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; |
| 2033 | name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; | 2051 | name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; |
| @@ -2047,12 +2065,9 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, | |||
| 2047 | decoded_name, | 2065 | decoded_name, |
| 2048 | decoded_name_size); | 2066 | decoded_name_size); |
| 2049 | if (rc) { | 2067 | if (rc) { |
| 2050 | printk(KERN_INFO "%s: Could not parse tag 70 packet " | 2068 | ecryptfs_printk(KERN_DEBUG, |
| 2051 | "from filename; copying through filename " | 2069 | "%s: Could not parse tag 70 packet from filename\n", |
| 2052 | "as-is\n", __func__); | 2070 | __func__); |
| 2053 | rc = ecryptfs_copy_filename(plaintext_name, | ||
| 2054 | plaintext_name_size, | ||
| 2055 | orig_name, orig_name_size); | ||
| 2056 | goto out_free; | 2071 | goto out_free; |
| 2057 | } | 2072 | } |
| 2058 | } else { | 2073 | } else { |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index c74ed3ca3372..b76a9853325e 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
| @@ -82,17 +82,28 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name, | |||
| 82 | buf->sb, lower_name, | 82 | buf->sb, lower_name, |
| 83 | lower_namelen); | 83 | lower_namelen); |
| 84 | if (rc) { | 84 | if (rc) { |
| 85 | printk(KERN_ERR "%s: Error attempting to decode and decrypt " | 85 | if (rc != -EINVAL) { |
| 86 | "filename [%s]; rc = [%d]\n", __func__, lower_name, | 86 | ecryptfs_printk(KERN_DEBUG, |
| 87 | rc); | 87 | "%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n", |
| 88 | goto out; | 88 | __func__, lower_name, rc); |
| 89 | return rc; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* Mask -EINVAL errors as these are most likely due a plaintext | ||
| 93 | * filename present in the lower filesystem despite filename | ||
| 94 | * encryption being enabled. One unavoidable example would be | ||
| 95 | * the "lost+found" dentry in the root directory of an Ext4 | ||
| 96 | * filesystem. | ||
| 97 | */ | ||
| 98 | return 0; | ||
| 89 | } | 99 | } |
| 100 | |||
| 90 | buf->caller->pos = buf->ctx.pos; | 101 | buf->caller->pos = buf->ctx.pos; |
| 91 | rc = !dir_emit(buf->caller, name, name_size, ino, d_type); | 102 | rc = !dir_emit(buf->caller, name, name_size, ino, d_type); |
| 92 | kfree(name); | 103 | kfree(name); |
| 93 | if (!rc) | 104 | if (!rc) |
| 94 | buf->entries_written++; | 105 | buf->entries_written++; |
| 95 | out: | 106 | |
| 96 | return rc; | 107 | return rc; |
| 97 | } | 108 | } |
| 98 | 109 | ||
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 847904aa63a9..97d17eaeba07 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -395,8 +395,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 395 | 395 | ||
| 396 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 396 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
| 397 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 397 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
| 398 | if (mount_crypt_stat | 398 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { |
| 399 | && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) { | ||
| 400 | rc = ecryptfs_encrypt_and_encode_filename( | 399 | rc = ecryptfs_encrypt_and_encode_filename( |
| 401 | &encrypted_and_encoded_name, &len, | 400 | &encrypted_and_encoded_name, &len, |
| 402 | mount_crypt_stat, name, len); | 401 | mount_crypt_stat, name, len); |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index c89a58cfc991..e74fe84d0886 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
| @@ -1880,7 +1880,7 @@ find_next_matching_auth_tok: | |||
| 1880 | candidate_auth_tok = &auth_tok_list_item->auth_tok; | 1880 | candidate_auth_tok = &auth_tok_list_item->auth_tok; |
| 1881 | if (unlikely(ecryptfs_verbosity > 0)) { | 1881 | if (unlikely(ecryptfs_verbosity > 0)) { |
| 1882 | ecryptfs_printk(KERN_DEBUG, | 1882 | ecryptfs_printk(KERN_DEBUG, |
| 1883 | "Considering cadidate auth tok:\n"); | 1883 | "Considering candidate auth tok:\n"); |
| 1884 | ecryptfs_dump_auth_tok(candidate_auth_tok); | 1884 | ecryptfs_dump_auth_tok(candidate_auth_tok); |
| 1885 | } | 1885 | } |
| 1886 | rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig, | 1886 | rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig, |
