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 | |
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
-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, |