Merge remote-tracking branch 'origin/develop-3.0' into develop-3.0-jb
[firefly-linux-kernel-4.4.55.git] / fs / ecryptfs / crypto.c
index cbadc1bee6e7ecceeefa5131143e08783d006297..c6602d24517682c56bd2928c390174b834a05534 100644 (file)
@@ -266,7 +266,6 @@ void ecryptfs_destroy_mount_crypt_stat(
                                 &mount_crypt_stat->global_auth_tok_list,
                                 mount_crypt_stat_list) {
                list_del(&auth_tok->mount_crypt_stat_list);
-               mount_crypt_stat->num_global_auth_toks--;
                if (auth_tok->global_auth_tok_key
                    && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID))
                        key_put(auth_tok->global_auth_tok_key);
@@ -348,7 +347,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
        BUG_ON(!crypt_stat || !crypt_stat->tfm
               || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
        if (unlikely(ecryptfs_verbosity > 0)) {
-               ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n",
+               ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",
                                crypt_stat->key_size);
                ecryptfs_dump_hex(crypt_stat->key,
                                  crypt_stat->key_size);
@@ -413,23 +412,11 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
        rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
                                (extent_base + extent_offset));
        if (rc) {
-               ecryptfs_printk(KERN_ERR, "Error attempting to "
-                               "derive IV for extent [0x%.16x]; "
-                               "rc = [%d]\n", (extent_base + extent_offset),
-                               rc);
+               ecryptfs_printk(KERN_ERR, "Error attempting to derive IV for "
+                       "extent [0x%.16llx]; rc = [%d]\n",
+                       (unsigned long long)(extent_base + extent_offset), rc);
                goto out;
        }
-       if (unlikely(ecryptfs_verbosity > 0)) {
-               ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
-                               "with iv:\n");
-               ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
-               ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
-                               "encryption:\n");
-               ecryptfs_dump_hex((char *)
-                                 (page_address(page)
-                                  + (extent_offset * crypt_stat->extent_size)),
-                                 8);
-       }
        rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
                                          page, (extent_offset
                                                 * crypt_stat->extent_size),
@@ -442,14 +429,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
                goto out;
        }
        rc = 0;
-       if (unlikely(ecryptfs_verbosity > 0)) {
-               ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
-                               "rc = [%d]\n", (extent_base + extent_offset),
-                               rc);
-               ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
-                               "encryption:\n");
-               ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
-       }
 out:
        return rc;
 }
@@ -540,23 +519,11 @@ static int ecryptfs_decrypt_extent(struct page *page,
        rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
                                (extent_base + extent_offset));
        if (rc) {
-               ecryptfs_printk(KERN_ERR, "Error attempting to "
-                               "derive IV for extent [0x%.16x]; "
-                               "rc = [%d]\n", (extent_base + extent_offset),
-                               rc);
+               ecryptfs_printk(KERN_ERR, "Error attempting to derive IV for "
+                       "extent [0x%.16llx]; rc = [%d]\n",
+                       (unsigned long long)(extent_base + extent_offset), rc);
                goto out;
        }
-       if (unlikely(ecryptfs_verbosity > 0)) {
-               ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
-                               "with iv:\n");
-               ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
-               ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
-                               "decryption:\n");
-               ecryptfs_dump_hex((char *)
-                                 (page_address(enc_extent_page)
-                                  + (extent_offset * crypt_stat->extent_size)),
-                                 8);
-       }
        rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
                                          (extent_offset
                                           * crypt_stat->extent_size),
@@ -570,16 +537,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
                goto out;
        }
        rc = 0;
-       if (unlikely(ecryptfs_verbosity > 0)) {
-               ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; "
-                               "rc = [%d]\n", (extent_base + extent_offset),
-                               rc);
-               ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
-                               "decryption:\n");
-               ecryptfs_dump_hex((char *)(page_address(page)
-                                          + (extent_offset
-                                             * crypt_stat->extent_size)), 8);
-       }
 out:
        return rc;
 }
@@ -780,7 +737,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
        }
        ecryptfs_printk(KERN_DEBUG,
                        "Initializing cipher [%s]; strlen = [%d]; "
-                       "key_size_bits = [%d]\n",
+                       "key_size_bits = [%zd]\n",
                        crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
                        crypt_stat->key_size << 3);
        if (crypt_stat->tfm) {
@@ -1027,25 +984,25 @@ out:
 }
 
 /**
- * contains_ecryptfs_marker - check for the ecryptfs marker
+ * ecryptfs_validate_marker - check for the ecryptfs marker
  * @data: The data block in which to check
  *
- * Returns one if marker found; zero if not found
+ * Returns zero if marker found; -EINVAL if not found
  */
-static int contains_ecryptfs_marker(char *data)
+static int ecryptfs_validate_marker(char *data)
 {
        u32 m_1, m_2;
 
        m_1 = get_unaligned_be32(data);
        m_2 = get_unaligned_be32(data + 4);
        if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2)
-               return 1;
+               return 0;
        ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; "
                        "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2,
                        MAGIC_ECRYPTFS_MARKER);
        ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = "
                        "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER));
-       return 0;
+       return -EINVAL;
 }
 
 struct ecryptfs_flag_map_elem {
@@ -1204,27 +1161,19 @@ int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code)
        return rc;
 }
 
-int ecryptfs_read_and_validate_header_region(char *data,
-                                            struct inode *ecryptfs_inode)
+int ecryptfs_read_and_validate_header_region(struct inode *inode)
 {
-       struct ecryptfs_crypt_stat *crypt_stat =
-               &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
+       u8 file_size[ECRYPTFS_SIZE_AND_MARKER_BYTES];
+       u8 *marker = file_size + ECRYPTFS_FILE_SIZE_BYTES;
        int rc;
 
-       if (crypt_stat->extent_size == 0)
-               crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
-       rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size,
-                                ecryptfs_inode);
-       if (rc < 0) {
-               printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n",
-                      __func__, rc);
-               goto out;
-       }
-       if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) {
-               rc = -EINVAL;
-       } else
-               rc = 0;
-out:
+       rc = ecryptfs_read_lower(file_size, 0, ECRYPTFS_SIZE_AND_MARKER_BYTES,
+                                inode);
+       if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
+               return rc >= 0 ? -EINVAL : rc;
+       rc = ecryptfs_validate_marker(marker);
+       if (!rc)
+               ecryptfs_i_size_init(file_size, inode);
        return rc;
 }
 
@@ -1245,8 +1194,7 @@ ecryptfs_write_header_metadata(char *virt,
        (*written) = 6;
 }
 
-struct kmem_cache *ecryptfs_header_cache_1;
-struct kmem_cache *ecryptfs_header_cache_2;
+struct kmem_cache *ecryptfs_header_cache;
 
 /**
  * ecryptfs_write_headers_virt
@@ -1391,6 +1339,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = -ENOMEM;
                goto out;
        }
+       /* Zeroed page ensures the in-header unencrypted i_size is set to 0 */
        rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat,
                                         ecryptfs_dentry);
        if (unlikely(rc)) {
@@ -1454,6 +1403,25 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
        crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 }
 
+void ecryptfs_i_size_init(const char *page_virt, struct inode *inode)
+{
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+       struct ecryptfs_crypt_stat *crypt_stat;
+       u64 file_size;
+
+       crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+       mount_crypt_stat =
+               &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
+       if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
+               file_size = i_size_read(ecryptfs_inode_to_lower(inode));
+               if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
+                       file_size += crypt_stat->metadata_size;
+       } else
+               file_size = get_unaligned_be64(page_virt);
+       i_size_write(inode, (loff_t)file_size);
+       crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED;
+}
+
 /**
  * ecryptfs_read_headers_virt
  * @page_virt: The virtual address into which to read the headers
@@ -1479,11 +1447,11 @@ static int ecryptfs_read_headers_virt(char *page_virt,
        crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private(
                ecryptfs_dentry->d_sb)->mount_crypt_stat;
        offset = ECRYPTFS_FILE_SIZE_BYTES;
-       rc = contains_ecryptfs_marker(page_virt + offset);
-       if (rc == 0) {
-               rc = -EINVAL;
+       rc = ecryptfs_validate_marker(page_virt + offset);
+       if (rc)
                goto out;
-       }
+       if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED))
+               ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
        offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
        rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset),
                                    &bytes_read);
@@ -1548,20 +1516,21 @@ out:
        return rc;
 }
 
-int ecryptfs_read_and_validate_xattr_region(char *page_virt,
-                                           struct dentry *ecryptfs_dentry)
+int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry,
+                                           struct inode *inode)
 {
+       u8 file_size[ECRYPTFS_SIZE_AND_MARKER_BYTES];
+       u8 *marker = file_size + ECRYPTFS_FILE_SIZE_BYTES;
        int rc;
 
-       rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry->d_inode);
-       if (rc)
-               goto out;
-       if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) {
-               printk(KERN_WARNING "Valid data found in [%s] xattr, but "
-                       "the marker is invalid\n", ECRYPTFS_XATTR_NAME);
-               rc = -EINVAL;
-       }
-out:
+       rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
+                                    ECRYPTFS_XATTR_NAME, file_size,
+                                    ECRYPTFS_SIZE_AND_MARKER_BYTES);
+       if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES)
+               return rc >= 0 ? -EINVAL : rc;
+       rc = ecryptfs_validate_marker(marker);
+       if (!rc)
+               ecryptfs_i_size_init(file_size, inode);
        return rc;
 }
 
@@ -1591,7 +1560,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
        ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
                                                      mount_crypt_stat);
        /* Read the first page from the underlying file */
-       page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER);
+       page_virt = kmem_cache_alloc(ecryptfs_header_cache, GFP_USER);
        if (!page_virt) {
                rc = -ENOMEM;
                printk(KERN_ERR "%s: Unable to allocate page_virt\n",
@@ -1609,7 +1578,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
                rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
                if (rc) {
                        printk(KERN_DEBUG "Valid eCryptfs headers not found in "
-                              "file header region or xattr region\n");
+                              "file header region or xattr region, inode %lu\n",
+                               ecryptfs_inode->i_ino);
                        rc = -EINVAL;
                        goto out;
                }
@@ -1618,7 +1588,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
                                                ECRYPTFS_DONT_VALIDATE_HEADER_SIZE);
                if (rc) {
                        printk(KERN_DEBUG "Valid eCryptfs headers not found in "
-                              "file xattr region either\n");
+                              "file xattr region either, inode %lu\n",
+                               ecryptfs_inode->i_ino);
                        rc = -EINVAL;
                }
                if (crypt_stat->mount_crypt_stat->flags
@@ -1629,14 +1600,15 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
                               "crypto metadata only in the extended attribute "
                               "region, but eCryptfs was mounted without "
                               "xattr support enabled. eCryptfs will not treat "
-                              "this like an encrypted file.\n");
+                              "this like an encrypted file, inode %lu\n",
+                               ecryptfs_inode->i_ino);
                        rc = -EINVAL;
                }
        }
 out:
        if (page_virt) {
                memset(page_virt, 0, PAGE_CACHE_SIZE);
-               kmem_cache_free(ecryptfs_header_cache_1, page_virt);
+               kmem_cache_free(ecryptfs_header_cache, page_virt);
        }
        return rc;
 }
@@ -1934,7 +1906,7 @@ static unsigned char *portable_filename_chars = ("-.0123456789ABCD"
 
 /* We could either offset on every reverse map or just pad some 0x00's
  * at the front here */
-static const unsigned char filename_rev_map[] = {
+static const unsigned char filename_rev_map[256] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 15 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */
@@ -1950,7 +1922,7 @@ static const unsigned char filename_rev_map[] = {
        0x00, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, /* 103 */
        0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, /* 111 */
        0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, /* 119 */
-       0x3D, 0x3E, 0x3F
+       0x3D, 0x3E, 0x3F /* 123 - 255 initialized to 0x00 */
 };
 
 /**