From: Michael Halcrow <mhalcrow@us.ibm.com>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, bdriessen@escrypt.com,
shaggy@us.ibm.com, sandeen@redhat.com, tchicks@us.ibm.com,
trevor.highland@gmail.com
Subject: [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page
Date: Sun, 2 Mar 2008 00:44:52 -0600 [thread overview]
Message-ID: <20080302064452.GD4627@localhost.austin.ibm.com> (raw)
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;
}
next reply other threads:[~2008-03-02 6:49 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-02 6:44 Michael Halcrow [this message]
2008-03-02 14:04 ` [PATCH] eCryptfs: Make ecryptfs_prepare_write decrypt the page Josh Boyer
2008-03-02 15:47 ` Michael Halcrow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080302064452.GD4627@localhost.austin.ibm.com \
--to=mhalcrow@us.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=bdriessen@escrypt.com \
--cc=linux-kernel@vger.kernel.org \
--cc=sandeen@redhat.com \
--cc=shaggy@us.ibm.com \
--cc=tchicks@us.ibm.com \
--cc=trevor.highland@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.