summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMilan Broz <gmazyland@gmail.com>2014-04-14 22:02:30 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-07 10:28:12 -0700
commitc80498a9f6b91d35bc6b6dfd185886d8d4346d43 (patch)
tree8c09795b6354696d971086f3050d4febf5e5f60c /drivers
parent14f7702f692048e1426d763457a34cb02e5c4267 (diff)
downloadlwn-c80498a9f6b91d35bc6b6dfd185886d8d4346d43.tar.gz
lwn-c80498a9f6b91d35bc6b6dfd185886d8d4346d43.zip
dm verity: fix biovecs hash calculation regression
commit 3a7745215e7f73a5c7d9bcdc50661a55b39052a3 upstream. Commit 003b5c5719f159f4f4bf97511c4702a0638313dd ("block: Convert drivers to immutable biovecs") incorrectly converted biovec iteration in dm-verity to always calculate the hash from a full biovec, but the function only needs to calculate the hash from part of the biovec (up to the calculated "todo" value). Fix this issue by limiting hash input to only the requested data size. This problem was identified using the cryptsetup regression test for veritysetup (verity-compat-test). Signed-off-by: Milan Broz <gmazyland@gmail.com> Acked-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-verity.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
index 796007a5e0e1..7a7bab8947ae 100644
--- a/drivers/md/dm-verity.c
+++ b/drivers/md/dm-verity.c
@@ -330,15 +330,17 @@ test_block_hash:
return r;
}
}
-
todo = 1 << v->data_dev_block_bits;
- while (io->iter.bi_size) {
+ do {
u8 *page;
+ unsigned len;
struct bio_vec bv = bio_iter_iovec(bio, io->iter);
page = kmap_atomic(bv.bv_page);
- r = crypto_shash_update(desc, page + bv.bv_offset,
- bv.bv_len);
+ len = bv.bv_len;
+ if (likely(len >= todo))
+ len = todo;
+ r = crypto_shash_update(desc, page + bv.bv_offset, len);
kunmap_atomic(page);
if (r < 0) {
@@ -346,8 +348,9 @@ test_block_hash:
return r;
}
- bio_advance_iter(bio, &io->iter, bv.bv_len);
- }
+ bio_advance_iter(bio, &io->iter, len);
+ todo -= len;
+ } while (todo);
if (!v->version) {
r = crypto_shash_update(desc, v->salt, v->salt_size);