From: Michael Halcrow <mhalcrow@google.com>
To: linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org
Cc: zohar@linux.vnet.ibm.com, mhalcrow@google.com,
herbert@gondor.apana.org.au, pavel@ucw.cz, hch@infradead.org,
lczerner@redhat.com, tytso@mit.edu, tyhicks@canonical.com,
serge.hallyn@canonical.com
Subject: [PATCH 5/5] ext4: Implements real encryption in the EXT4 write and read paths
Date: Wed, 23 Jul 2014 14:23:28 -0700 [thread overview]
Message-ID: <1406150608-19351-6-git-send-email-mhalcrow@google.com> (raw)
In-Reply-To: <1406150608-19351-1-git-send-email-mhalcrow@google.com>
Implements real encryption in the EXT4 write and read paths.
Signed-off-by: Michael Halcrow <mhalcrow@google.com>
---
fs/ext4/crypto.c | 65 +++++++++++++++++++++++---------------------------------
fs/ext4/inode.c | 9 +++++++-
2 files changed, 34 insertions(+), 40 deletions(-)
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 435f33f..a17b23b 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -353,9 +353,10 @@ struct page *ext4_encrypt(ext4_crypto_ctx_t *ctx, struct page *plaintext_page)
ciphertext_page = ERR_PTR(-ENOMEM);
goto out;
}
- ablkcipher_request_set_callback(req,
- CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
- ext4_crypt_complete, &ecr);
+ ablkcipher_request_set_callback(
+ req,
+ CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
+ ext4_crypt_complete, &ecr);
ext4_xts_tweak_for_page(xts_tweak, plaintext_page);
sg_init_table(&dst, 1);
sg_init_table(&src, 1);
@@ -363,20 +364,20 @@ struct page *ext4_encrypt(ext4_crypto_ctx_t *ctx, struct page *plaintext_page)
sg_set_page(&src, plaintext_page, PAGE_CACHE_SIZE, 0);
ablkcipher_request_set_crypt(req, &src, &dst, PAGE_CACHE_SIZE,
xts_tweak);
+ res = crypto_ablkcipher_encrypt(req);
+ if (res == -EINPROGRESS || res == -EBUSY) {
+ BUG_ON(req->base.data != &ecr);
+ wait_for_completion(&ecr.completion);
+ res = ecr.res;
+ reinit_completion(&ecr.completion);
+ }
ablkcipher_request_free(req);
-/* =======
- * TODO(mhalcrow): Removed real crypto so intermediate patch
- * for write path is still fully functional. */
- {
- /* TODO(mhalcrow): Temporary for testing */
- char *ciphertext_virt, *plaintext_virt;
- ciphertext_virt = kmap(ciphertext_page);
- plaintext_virt = kmap(plaintext_page);
- memcpy(ciphertext_virt, plaintext_virt, PAGE_CACHE_SIZE);
- kunmap(plaintext_page);
- kunmap(ciphertext_page);
+ if (res) {
+ printk_ratelimited(KERN_ERR "%s: crypto_ablkcipher_encrypt() "
+ "returned %d\n", __func__, res);
+ ciphertext_page = ERR_PTR(res);
+ goto out;
}
-/* ======= */
SetPageDirty(ciphertext_page);
SetPagePrivate(ciphertext_page);
ctx->control_page = plaintext_page;
@@ -410,9 +411,10 @@ int ext4_decrypt(ext4_crypto_ctx_t *ctx, struct page* page)
res = -ENOMEM;
goto out;
}
- ablkcipher_request_set_callback(req,
- CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
- ext4_crypt_complete, &ecr);
+ ablkcipher_request_set_callback(
+ req,
+ CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
+ ext4_crypt_complete, &ecr);
ext4_xts_tweak_for_page(xts_tweak, page);
sg_init_table(&dst, 1);
sg_init_table(&src, 1);
@@ -420,28 +422,13 @@ int ext4_decrypt(ext4_crypto_ctx_t *ctx, struct page* page)
sg_set_page(&src, page, PAGE_CACHE_SIZE, 0);
ablkcipher_request_set_crypt(req, &src, &dst, PAGE_CACHE_SIZE,
xts_tweak);
-/* =======
- * TODO(mhalcrow): Removed real crypto so intermediate patch for read
- * path is still fully functional. For now just doing something that
- * might expose a race condition. */
- {
- char *page_virt;
- char tmp;
- int i;
- page_virt = kmap(page);
- for (i = 0; i < PAGE_CACHE_SIZE / 2; ++i) {
- tmp = page_virt[i];
- page_virt[i] = page_virt[PAGE_CACHE_SIZE - i - 1];
- page_virt[PAGE_CACHE_SIZE - i - 1] = tmp;
- }
- for (i = 0; i < PAGE_CACHE_SIZE / 2; ++i) {
- tmp = page_virt[i];
- page_virt[i] = page_virt[PAGE_CACHE_SIZE - i - 1];
- page_virt[PAGE_CACHE_SIZE - i - 1] = tmp;
- }
- kunmap(page);
+ res = crypto_ablkcipher_decrypt(req);
+ if (res == -EINPROGRESS || res == -EBUSY) {
+ BUG_ON(req->base.data != &ecr);
+ wait_for_completion(&ecr.completion);
+ res = ecr.res;
+ reinit_completion(&ecr.completion);
}
-/* ======= */
ablkcipher_request_free(req);
out:
if (res)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 6bf57d3..a0e80b7 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2848,6 +2848,8 @@ static void ext4_completion_work(struct work_struct *work)
ext4_crypto_ctx_t *ctx = container_of(work, ext4_crypto_ctx_t, work);
struct page *page = ctx->control_page;
WARN_ON_ONCE(ext4_decrypt(ctx, page));
+ atomic_dec(&ctx->dbg_refcnt);
+ BUG_ON(atomic_read(&ctx->dbg_refcnt) != 0);
ext4_release_crypto_ctx(ctx);
SetPageUptodate(page);
unlock_page(page);
@@ -2859,6 +2861,8 @@ static int ext4_complete_cb(struct bio *bio, int res)
struct page *page = ctx->control_page;
BUG_ON(atomic_read(&ctx->dbg_refcnt) != 1);
if (res) {
+ atomic_dec(&ctx->dbg_refcnt);
+ BUG_ON(atomic_read(&ctx->dbg_refcnt) != 0);
ext4_release_crypto_ctx(ctx);
unlock_page(page);
return res;
@@ -2962,8 +2966,11 @@ static int ext4_read_full_page(struct page *page)
BUG_ON(ctx->control_page);
ctx->control_page = page;
BUG_ON(atomic_read(&ctx->dbg_refcnt) != 1);
- if (submit_bh_cb(READ, bh, ext4_complete_cb, ctx))
+ if (submit_bh_cb(READ, bh, ext4_complete_cb, ctx)) {
+ atomic_dec(&ctx->dbg_refcnt);
+ BUG_ON(atomic_read(&ctx->dbg_refcnt) != 0);
ext4_release_crypto_ctx(ctx);
+ }
}
}
return 0;
--
2.0.0.526.g5318336
next prev parent reply other threads:[~2014-07-23 21:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-23 21:23 [PATCH 0/5] ext4: RFC: Encryption Michael Halcrow
2014-07-23 21:23 ` [PATCH 1/5] ext4: Adds callback support for bio read completion Michael Halcrow
2014-07-23 21:23 ` [PATCH 2/5] ext4: Adds EXT4 encryption facilities Michael Halcrow
2014-07-23 21:23 ` [PATCH 3/5] ext4: Implements the EXT4 encryption write path Michael Halcrow
2014-07-23 21:23 ` [PATCH 4/5] ext4: Adds EXT4 encryption read callback support Michael Halcrow
2014-08-05 23:06 ` Mimi Zohar
2014-07-23 21:23 ` Michael Halcrow [this message]
2014-07-23 22:25 ` [PATCH 0/5] ext4: RFC: Encryption Pavel Machek
2014-07-23 22:34 ` Pavel Machek
2014-07-23 22:39 ` Michael Halcrow
2014-07-23 22:39 ` Andreas Dilger
2014-07-23 23:01 ` Michael Halcrow
2014-07-24 12:26 ` Theodore Ts'o
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=1406150608-19351-6-git-send-email-mhalcrow@google.com \
--to=mhalcrow@google.com \
--cc=hch@infradead.org \
--cc=herbert@gondor.apana.org.au \
--cc=lczerner@redhat.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=serge.hallyn@canonical.com \
--cc=tyhicks@canonical.com \
--cc=tytso@mit.edu \
--cc=zohar@linux.vnet.ibm.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 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).