Merge tag 'pinctrl-v4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[linux-2.6-block.git] / fs / ecryptfs / crypto.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 {