eCryptfs: Strip metadata in xattr flag in encrypted view

The ecryptfs_encrypted_view mount option provides a unified way of
viewing encrypted eCryptfs files. If the metadata is stored in a xattr,
the metadata is moved to the file header when the file is read inside
the eCryptfs mount. Because of this, we should strip the
ECRYPTFS_METADATA_IN_XATTR flag from the header's flag section. This
allows eCryptfs to treat the file as an eCryptfs file with a header
at the front.

Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>

+22 -4
+5 -4
fs/ecryptfs/crypto.c
··· 1107 (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; 1108 } 1109 1110 - static void 1111 - write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, 1112 - size_t *written) 1113 { 1114 u32 flags = 0; 1115 int i; ··· 1290 offset = ECRYPTFS_FILE_SIZE_BYTES; 1291 write_ecryptfs_marker((page_virt + offset), &written); 1292 offset += written; 1293 - write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); 1294 offset += written; 1295 ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, 1296 &written);
··· 1107 (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; 1108 } 1109 1110 + void ecryptfs_write_crypt_stat_flags(char *page_virt, 1111 + struct ecryptfs_crypt_stat *crypt_stat, 1112 + size_t *written) 1113 { 1114 u32 flags = 0; 1115 int i; ··· 1290 offset = ECRYPTFS_FILE_SIZE_BYTES; 1291 write_ecryptfs_marker((page_virt + offset), &written); 1292 offset += written; 1293 + ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat, 1294 + &written); 1295 offset += written; 1296 ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, 1297 &written);
+3
fs/ecryptfs/ecryptfs_kernel.h
··· 659 int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); 660 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); 661 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); 662 int ecryptfs_read_and_validate_header_region(char *data, 663 struct inode *ecryptfs_inode); 664 int ecryptfs_read_and_validate_xattr_region(char *page_virt,
··· 659 int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); 660 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); 661 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); 662 + void ecryptfs_write_crypt_stat_flags(char *page_virt, 663 + struct ecryptfs_crypt_stat *crypt_stat, 664 + size_t *written); 665 int ecryptfs_read_and_validate_header_region(char *data, 666 struct inode *ecryptfs_inode); 667 int ecryptfs_read_and_validate_xattr_region(char *page_virt,
+14
fs/ecryptfs/mmap.c
··· 82 return rc; 83 } 84 85 /** 86 * Header Extent: 87 * Octets 0-7: Unencrypted file size (big-endian) ··· 149 150 rc = ecryptfs_read_xattr_region( 151 page_virt, page->mapping->host); 152 ecryptfs_write_header_metadata(page_virt + 20, 153 crypt_stat, 154 &written);
··· 82 return rc; 83 } 84 85 + static void strip_xattr_flag(char *page_virt, 86 + struct ecryptfs_crypt_stat *crypt_stat) 87 + { 88 + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { 89 + size_t written; 90 + 91 + crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR; 92 + ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat, 93 + &written); 94 + crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; 95 + } 96 + } 97 + 98 /** 99 * Header Extent: 100 * Octets 0-7: Unencrypted file size (big-endian) ··· 136 137 rc = ecryptfs_read_xattr_region( 138 page_virt, page->mapping->host); 139 + strip_xattr_flag(page_virt + 16, crypt_stat); 140 ecryptfs_write_header_metadata(page_virt + 20, 141 crypt_stat, 142 &written);