Merge tag 'ecryptfs-4.17-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Apr 2018 16:08:37 +0000 (09:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Apr 2018 16:08:37 +0000 (09:08 -0700)
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

fs/ecryptfs/crypto.c
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c

index 846ca150d52e9259e5ded67abfe708a9f5c4084e..4dd842f728465591cc7982d635f544c0084b064a 100644 (file)
@@ -1997,6 +1997,16 @@ out:
        return rc;
 }
 
+static bool is_dot_dotdot(const char *name, size_t name_size)
+{
+       if (name_size == 1 && name[0] == '.')
+               return true;
+       else if (name_size == 2 && name[0] == '.' && name[1] == '.')
+               return true;
+
+       return false;
+}
+
 /**
  * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext
  * @plaintext_name: The plaintext name
@@ -2021,13 +2031,21 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
        size_t packet_size;
        int rc = 0;
 
-       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-           && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
-           && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)
-           && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
-                       ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) {
-               const char *orig_name = name;
-               size_t orig_name_size = name_size;
+       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) &&
+           !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)) {
+               if (is_dot_dotdot(name, name_size)) {
+                       rc = ecryptfs_copy_filename(plaintext_name,
+                                                   plaintext_name_size,
+                                                   name, name_size);
+                       goto out;
+               }
+
+               if (name_size <= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE ||
+                   strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
+                           ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)) {
+                       rc = -EINVAL;
+                       goto out;
+               }
 
                name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
                name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
@@ -2047,12 +2065,9 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
                                                  decoded_name,
                                                  decoded_name_size);
                if (rc) {
-                       printk(KERN_INFO "%s: Could not parse tag 70 packet "
-                              "from filename; copying through filename "
-                              "as-is\n", __func__);
-                       rc = ecryptfs_copy_filename(plaintext_name,
-                                                   plaintext_name_size,
-                                                   orig_name, orig_name_size);
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "%s: Could not parse tag 70 packet from filename\n",
+                                       __func__);
                        goto out_free;
                }
        } else {
index c74ed3ca3372f8b8e91ed9da35de617c7b25ce08..b76a9853325e7034a0c40f4d6099bfb83ef21c94 100644 (file)
@@ -82,17 +82,28 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
                                                  buf->sb, lower_name,
                                                  lower_namelen);
        if (rc) {
-               printk(KERN_ERR "%s: Error attempting to decode and decrypt "
-                      "filename [%s]; rc = [%d]\n", __func__, lower_name,
-                      rc);
-               goto out;
+               if (rc != -EINVAL) {
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
+                                       __func__, lower_name, rc);
+                       return rc;
+               }
+
+               /* Mask -EINVAL errors as these are most likely due a plaintext
+                * filename present in the lower filesystem despite filename
+                * encryption being enabled. One unavoidable example would be
+                * the "lost+found" dentry in the root directory of an Ext4
+                * filesystem.
+                */
+               return 0;
        }
+
        buf->caller->pos = buf->ctx.pos;
        rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
        kfree(name);
        if (!rc)
                buf->entries_written++;
-out:
+
        return rc;
 }
 
index 847904aa63a9a6554d592dbf0710c7eff7954f49..97d17eaeba0731fb5d755c7a3106af1abaf2cff0 100644 (file)
@@ -395,8 +395,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
 
        mount_crypt_stat = &ecryptfs_superblock_to_private(
                                ecryptfs_dentry->d_sb)->mount_crypt_stat;
-       if (mount_crypt_stat
-           && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) {
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
                rc = ecryptfs_encrypt_and_encode_filename(
                        &encrypted_and_encoded_name, &len,
                        mount_crypt_stat, name, len);
index c89a58cfc991c235f1420a4901df877dc7557939..e74fe84d0886879c04cc26297f0e8b27db8281a6 100644 (file)
@@ -1880,7 +1880,7 @@ find_next_matching_auth_tok:
                candidate_auth_tok = &auth_tok_list_item->auth_tok;
                if (unlikely(ecryptfs_verbosity > 0)) {
                        ecryptfs_printk(KERN_DEBUG,
-                                       "Considering cadidate auth tok:\n");
+                                       "Considering candidate auth tok:\n");
                        ecryptfs_dump_auth_tok(candidate_auth_tok);
                }
                rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig,