All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nathan Huckleberry <nhuck@google.com>
To: Mike Snitzer <snitzer@kernel.org>
Cc: Eric Biggers <ebiggers@kernel.org>,
	dm-devel@redhat.com, Milan Broz <gmazyland@gmail.com>,
	Sami Tolvanen <samitolvanen@google.com>,
	Nathan Huckleberry <nhuck@google.com>
Subject: Re: [dm-devel] [PATCH] Fixes 6890e9b8c7d0a1062bbf4f854b6be3723836ad9a
Date: Wed,  3 Aug 2022 18:29:05 +0000	[thread overview]
Message-ID: <20220803182905.3279728-1-nhuck@google.com> (raw)
In-Reply-To: <YuqffhXctdt9vM0i@redhat.com>

The previous patch had a bug when hash verification failed in the
tasklet.  This happened because the tasklet has already advanced the
bvec_iter when it falls back to the work-queue implementation.  When the
work-queue job begins running, it attempts to restart verifiying at
block i, but the bvec_iter is at block i+1.

This causes several failures, the most noticeable is that there are not
enough bytes in the bvec_iter to finish verification.  Since there are
not enough bytes to finish, the work queue gets stuck in an infinite
loop in verity_for_io_block.

To fix this, we can make a local copy of the bvec_iter struct in
verity_verify_io.  This requires that we restart verification from the
first block when deferring to a work-queue rather than starting from the
last block verified in the tasklet.

This patch also fixes what appears to be a memory leak when FEC is
enabled.  The call to verity_fec_init_io should only be made if we are
in a work-queue since a tasklet does not use FEC and is unable to free
the memory.

Signed-off-by: Nathan Huckleberry <nhuck@google.com>
---
 drivers/md/dm-verity-target.c | 23 ++++++++++++++---------
 drivers/md/dm-verity.h        |  1 -
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 144889ba43ea..0677795454d7 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -499,17 +499,23 @@ static int verity_verify_io(struct dm_verity_io *io)
 	bool is_zero;
 	struct dm_verity *v = io->v;
 	struct bvec_iter start;
+	/*
+	 * Copy the iterator in case we need to restart verification in a
+	 * work-queue.
+	 */
+	struct bvec_iter iter_copy = io->iter;
 	struct crypto_wait wait;
 	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
+	unsigned int b;
 
-	for (; io->block_idx < io->n_blocks; io->block_idx++) {
+	for (b = 0; b < io->n_blocks; b++) {
 		int r;
-		sector_t cur_block = io->block + io->block_idx;
+		sector_t cur_block = io->block + b;
 		struct ahash_request *req = verity_io_hash_req(v, io);
 
 		if (v->validated_blocks &&
 		    likely(test_bit(cur_block, v->validated_blocks))) {
-			verity_bv_skip_block(v, io, &io->iter);
+			verity_bv_skip_block(v, io, &iter_copy);
 			continue;
 		}
 
@@ -524,7 +530,7 @@ static int verity_verify_io(struct dm_verity_io *io)
 			 * If we expect a zero block, don't validate, just
 			 * return zeros.
 			 */
-			r = verity_for_bv_block(v, io, &io->iter,
+			r = verity_for_bv_block(v, io, &iter_copy,
 						verity_bv_zero);
 			if (unlikely(r < 0))
 				return r;
@@ -536,8 +542,8 @@ static int verity_verify_io(struct dm_verity_io *io)
 		if (unlikely(r < 0))
 			return r;
 
-		start = io->iter;
-		r = verity_for_io_block(v, io, &io->iter, &wait);
+		start = iter_copy;
+		r = verity_for_io_block(v, io, &iter_copy, &wait);
 		if (unlikely(r < 0))
 			return r;
 
@@ -608,6 +614,8 @@ static void verity_work(struct work_struct *w)
 	struct dm_verity_io *io = container_of(w, struct dm_verity_io, work);
 
 	io->in_tasklet = false;
+	verity_fec_init_io(io);
+
 	verity_finish_io(io, errno_to_blk_status(verity_verify_io(io)));
 }
 
@@ -638,7 +646,6 @@ static void verity_end_io(struct bio *bio)
 		return;
 	}
 
-	io->block_idx = 0;
 	if (static_branch_unlikely(&use_tasklet_enabled) && io->v->use_tasklet) {
 		tasklet_init(&io->tasklet, verity_tasklet, (unsigned long)io);
 		tasklet_schedule(&io->tasklet);
@@ -756,8 +763,6 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
 	bio->bi_private = io;
 	io->iter = bio->bi_iter;
 
-	verity_fec_init_io(io);
-
 	verity_submit_prefetch(v, io);
 
 	submit_bio_noacct(bio);
diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
index e73a7972c3e9..fb92b22a6404 100644
--- a/drivers/md/dm-verity.h
+++ b/drivers/md/dm-verity.h
@@ -78,7 +78,6 @@ struct dm_verity_io {
 
 	sector_t block;
 	unsigned n_blocks;
-	unsigned int block_idx;
 	bool in_tasklet;
 
 	struct bvec_iter iter;
-- 
2.37.1.455.g008518b4e5-goog

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


  reply	other threads:[~2022-08-03 18:29 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-26 16:09 [dm-devel] [PATCH v2 0/6] dm verity: optionally use tasklets Mike Snitzer
2022-07-26 16:09 ` [dm-devel] [PATCH v2 1/6] dm bufio: Add flags argument to dm_bufio_client_create Mike Snitzer
2022-07-26 16:09 ` [dm-devel] [PATCH v2 2/6] dm bufio: Add DM_BUFIO_CLIENT_NO_SLEEP flag Mike Snitzer
2022-07-27 15:25   ` Mikulas Patocka
2022-07-27 15:47     ` Mike Snitzer
2022-07-27 19:53       ` Nathan Huckleberry
2022-07-28 22:37         ` Mike Snitzer
2022-07-26 16:09 ` [dm-devel] [PATCH v2 3/6] dm verity: Add optional "try_verify_in_tasklet" feature Mike Snitzer
2022-07-26 16:09 ` [dm-devel] [PATCH v2 4/6] dm verity: allow optional args to alter primary args handling Mike Snitzer
2022-07-26 16:09 ` [dm-devel] [PATCH v2 5/6] dm bufio: conditionally enable branching for DM_BUFIO_CLIENT_NO_SLEEP Mike Snitzer
2022-07-26 16:09 ` [dm-devel] [PATCH v2 6/6] dm verity: conditionally enable branching for "try_verify_in_tasklet" Mike Snitzer
2022-07-26 20:18 ` [dm-devel] [PATCH v2 0/6] dm verity: optionally use tasklets Nathan Huckleberry
2022-07-26 21:44 ` Milan Broz
2022-07-26 23:04   ` Mike Snitzer
2022-07-27  8:23     ` Milan Broz
2022-08-03  1:39       ` Nathan Huckleberry
2022-08-03 16:17         ` Mike Snitzer
2022-08-03 18:29           ` Nathan Huckleberry [this message]
2022-08-04 20:22             ` [dm-devel] Fixes 6890e9b8c7d0a1062bbf4f854b6be3723836ad9a Mike Snitzer

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=20220803182905.3279728-1-nhuck@google.com \
    --to=nhuck@google.com \
    --cc=dm-devel@redhat.com \
    --cc=ebiggers@kernel.org \
    --cc=gmazyland@gmail.com \
    --cc=samitolvanen@google.com \
    --cc=snitzer@kernel.org \
    /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.