summaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/mmap.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-02-12 00:53:47 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 09:48:36 -0800
commite77a56ddceeec87575a13a60fc1a394af6a1f4bc (patch)
tree8be21cc4afbc0596716bc9d4d8dd145dd8c74252 /fs/ecryptfs/mmap.c
parentdd2a3b7ad98f8482cae481cad89dfed5eee48365 (diff)
[PATCH] eCryptfs: Encrypted passthrough
Provide an option to provide a view of the encrypted files such that the metadata is always in the header of the files, regardless of whether the metadata is actually in the header or in the extended attribute. This mode of operation is useful for applications like incremental backup utilities that do not preserve the extended attributes when directly accessing the lower files. With this option enabled, the files under the eCryptfs mount point will be read-only. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r--fs/ecryptfs/mmap.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index ba3650d03c4..3386014becc 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -260,6 +260,33 @@ out:
ClearPageUptodate(page);
return rc;
}
+/**
+ * Header Extent:
+ * Octets 0-7: Unencrypted file size (big-endian)
+ * Octets 8-15: eCryptfs special marker
+ * Octets 16-19: Flags
+ * Octet 16: File format version number (between 0 and 255)
+ * Octets 17-18: Reserved
+ * Octet 19: Bit 1 (lsb): Reserved
+ * Bit 2: Encrypted?
+ * Bits 3-8: Reserved
+ * Octets 20-23: Header extent size (big-endian)
+ * Octets 24-25: Number of header extents at front of file
+ * (big-endian)
+ * Octet 26: Begin RFC 2440 authentication token packet set
+ */
+static void set_header_info(char *page_virt,
+ struct ecryptfs_crypt_stat *crypt_stat)
+{
+ size_t written;
+ int save_num_header_extents_at_front =
+ crypt_stat->num_header_extents_at_front;
+
+ crypt_stat->num_header_extents_at_front = 1;
+ ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
+ crypt_stat->num_header_extents_at_front =
+ save_num_header_extents_at_front;
+}
/**
* ecryptfs_readpage
@@ -289,10 +316,55 @@ static int ecryptfs_readpage(struct file *file, struct page *page)
"[%d]\n", rc);
goto out;
}
+ } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
+ if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+ int num_pages_in_header_region =
+ (crypt_stat->header_extent_size
+ / PAGE_CACHE_SIZE);
+
+ if (page->index < num_pages_in_header_region) {
+ char *page_virt;
+
+ page_virt = (char *)kmap(page);
+ if (!page_virt) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Error mapping page\n");
+ goto out;
+ }
+ memset(page_virt, 0, PAGE_CACHE_SIZE);
+ if (page->index == 0) {
+ rc = ecryptfs_read_xattr_region(
+ page_virt, file->f_path.dentry);
+ set_header_info(page_virt, crypt_stat);
+ }
+ kunmap(page);
+ if (rc) {
+ printk(KERN_ERR "Error reading xattr "
+ "region\n");
+ goto out;
+ }
+ } else {
+ rc = ecryptfs_do_readpage(
+ file, page,
+ (page->index
+ - num_pages_in_header_region));
+ if (rc) {
+ printk(KERN_ERR "Error reading page; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
+ }
+ } else {
+ rc = ecryptfs_do_readpage(file, page, page->index);
+ if (rc) {
+ printk(KERN_ERR "Error reading page; rc = "
+ "[%d]\n", rc);
+ goto out;
+ }
+ }
} else {
rc = ecryptfs_decrypt_page(file, page);
if (rc) {
-
ecryptfs_printk(KERN_ERR, "Error decrypting page; "
"rc = [%d]\n", rc);
goto out;