LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page
@ 2008-03-02  6:44 Michael Halcrow
  2008-03-02 14:04 ` Josh Boyer
  0 siblings, 1 reply; 3+ messages in thread
From: Michael Halcrow @ 2008-03-02  6:44 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, bdriessen, shaggy, sandeen, tchicks, trevor.highland

When the page is not up to date, ecryptfs_prepare_write() should be
acting much like ecryptfs_readpage(). This includes the painfully
obvious step of actually decrypting the page contents read from the
lower encrypted file.

Note that this patch resolves a bug in eCryptfs in 2.6.24 that one can
produce with these steps:

# mount -t ecryptfs /secret /secret
# echo "abc" > /secret/file.txt
# umount /secret
# mount -t ecryptfs /secret /secret
# echo "def" >> /secret/file.txt
# cat /secret/file.txt

Without this patch, the resulting data returned from cat is likely to
be something other than "abc\ndef\n".

(Thanks to Benedikt Driessen for reporting this.)

Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
 mmap.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 76 insertions(+), 26 deletions(-)

diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index dc74b18..6df1deb 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -263,52 +263,102 @@ out:
 	return 0;
 }
 
-/* This function must zero any hole we create */
+/**
+ * ecryptfs_prepare_write
+ * @file: The eCryptfs file
+ * @page: The eCryptfs page
+ * @from: The start byte from which we will write
+ * @to: The end byte to which we will write
+ *
+ * This function must zero any hole we create
+ *
+ * Returns zero on success; non-zero otherwise
+ */
 static int ecryptfs_prepare_write(struct file *file, struct page *page,
 				  unsigned from, unsigned to)
 {
-	int rc = 0;
 	loff_t prev_page_end_size;
+	int rc = 0;
 
 	if (!PageUptodate(page)) {
-		rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
-						      PAGE_CACHE_SIZE,
-						      page->mapping->host);
-		if (rc) {
-			printk(KERN_ERR "%s: Error attemping to read lower "
-			       "page segment; rc = [%d]\n", __FUNCTION__, rc);
-			ClearPageUptodate(page);
-			goto out;
-		} else
+		struct ecryptfs_crypt_stat *crypt_stat =
+			&ecryptfs_inode_to_private(
+				file->f_path.dentry->d_inode)->crypt_stat;
+
+		if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
+		    || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
+			rc = ecryptfs_read_lower_page_segment(
+				page, page->index, 0, PAGE_CACHE_SIZE,
+				page->mapping->host);
+			if (rc) {
+				printk(KERN_ERR "%s: Error attemping to read "
+				       "lower page segment; rc = [%d]\n",
+				       __FUNCTION__, rc);
+				ClearPageUptodate(page);
+				goto out;
+			} else
+				SetPageUptodate(page);
+		} else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
+			if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+				rc = ecryptfs_copy_up_encrypted_with_header(
+					page, crypt_stat);
+				if (rc) {
+					printk(KERN_ERR "%s: Error attempting "
+					       "to copy the encrypted content "
+					       "from the lower file whilst "
+					       "inserting the metadata from "
+					       "the xattr into the header; rc "
+					       "= [%d]\n", __FUNCTION__, rc);
+					ClearPageUptodate(page);
+					goto out;
+				}
+				SetPageUptodate(page);
+			} else {
+				rc = ecryptfs_read_lower_page_segment(
+					page, page->index, 0, PAGE_CACHE_SIZE,
+					page->mapping->host);
+				if (rc) {
+					printk(KERN_ERR "%s: Error reading "
+					       "page; rc = [%d]\n",
+					       __FUNCTION__, rc);
+					ClearPageUptodate(page);
+					goto out;
+				}
+				SetPageUptodate(page);
+			}
+		} else {
+			rc = ecryptfs_decrypt_page(page);
+			if (rc) {
+				printk(KERN_ERR "%s: Error decrypting page "
+				       "at index [%ld]; rc = [%d]\n",
+				       __FUNCTION__, page->index, rc);
+				ClearPageUptodate(page);
+				goto out;
+			}
 			SetPageUptodate(page);
+		}
 	}
-
 	prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
-
-	/*
-	 * If creating a page or more of holes, zero them out via truncate.
-	 * Note, this will increase i_size.
-	 */
+	/* If creating a page or more of holes, zero them out via truncate.
+	 * Note, this will increase i_size. */
 	if (page->index != 0) {
 		if (prev_page_end_size > i_size_read(page->mapping->host)) {
 			rc = ecryptfs_truncate(file->f_path.dentry,
 					       prev_page_end_size);
 			if (rc) {
-				printk(KERN_ERR "Error on attempt to "
+				printk(KERN_ERR "%s: Error on attempt to "
 				       "truncate to (higher) offset [%lld];"
-				       " rc = [%d]\n", prev_page_end_size, rc);
+				       " rc = [%d]\n", __FUNCTION__,
+				       prev_page_end_size, rc);
 				goto out;
 			}
 		}
 	}
-	/*
-	 * Writing to a new page, and creating a small hole from start of page?
-	 * Zero it out.
-	 */
-	if ((i_size_read(page->mapping->host) == prev_page_end_size) &&
-	    (from != 0)) {
+	/* Writing to a new page, and creating a small hole from start
+	 * of page?  Zero it out. */
+	if ((i_size_read(page->mapping->host) == prev_page_end_size)
+	    && (from != 0))
 		zero_user(page, 0, PAGE_CACHE_SIZE);
-	}
 out:
 	return rc;
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page
  2008-03-02  6:44 [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page Michael Halcrow
@ 2008-03-02 14:04 ` Josh Boyer
  2008-03-02 15:47   ` Michael Halcrow
  0 siblings, 1 reply; 3+ messages in thread
From: Josh Boyer @ 2008-03-02 14:04 UTC (permalink / raw)
  To: Michael Halcrow
  Cc: akpm, linux-kernel, bdriessen, shaggy, sandeen, tchicks, trevor.highland

On Sun, 2 Mar 2008 00:44:52 -0600
Michael Halcrow <mhalcrow@us.ibm.com> wrote:

> When the page is not up to date, ecryptfs_prepare_write() should be
> acting much like ecryptfs_readpage(). This includes the painfully
> obvious step of actually decrypting the page contents read from the
> lower encrypted file.
> 
> Note that this patch resolves a bug in eCryptfs in 2.6.24 that one can
> produce with these steps:

Should it go in -stable then?

josh

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page
  2008-03-02 14:04 ` Josh Boyer
@ 2008-03-02 15:47   ` Michael Halcrow
  0 siblings, 0 replies; 3+ messages in thread
From: Michael Halcrow @ 2008-03-02 15:47 UTC (permalink / raw)
  To: Josh Boyer
  Cc: akpm, linux-kernel, bdriessen, shaggy, sandeen, tchicks, trevor.highland

On Sun, Mar 02, 2008 at 08:04:52AM -0600, Josh Boyer wrote:
> On Sun, 2 Mar 2008 00:44:52 -0600
> Michael Halcrow <mhalcrow@us.ibm.com> wrote:
> 
> > When the page is not up to date, ecryptfs_prepare_write() should be
> > acting much like ecryptfs_readpage(). This includes the painfully
> > obvious step of actually decrypting the page contents read from the
> > lower encrypted file.
> > 
> > Note that this patch resolves a bug in eCryptfs in 2.6.24 that one can
> > produce with these steps:
> 
> Should it go in -stable then?

Yes; I recommend this fix for a future 2.6.24 release.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-03-02 15:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-02  6:44 [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page Michael Halcrow
2008-03-02 14:04 ` Josh Boyer
2008-03-02 15:47   ` Michael Halcrow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).