All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: fstests@vger.kernel.org
Cc: linux-fscrypt@vger.kernel.org
Subject: [PATCH v3 09/10] generic/624: test multiple Merkle tree block sizes
Date: Thu, 29 Dec 2022 15:32:21 -0800	[thread overview]
Message-ID: <20221229233222.119630-10-ebiggers@kernel.org> (raw)
In-Reply-To: <20221229233222.119630-1-ebiggers@kernel.org>

From: Eric Biggers <ebiggers@google.com>

Instead of only testing 4K Merkle tree blocks, test FSV_BLOCK_SIZE, and
also other sizes if they happen to be supported.  This allows this test
to run in cases where it couldn't before and improves test coverage in
cases where it did run before.

This required reworking the test to compute the expected digests using
the 'fsverity digest' command, instead of relying on .out file
comparisons.  (There isn't much downside to this, since comparison to
known-good file digests already happens in generic/575.  So if both the
kernel and fsverity-utils were to be broken in the same way, generic/575
would detect it.  generic/624 serves a different purpose.)

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/verity         |  11 ++++
 tests/generic/624     | 119 ++++++++++++++++++++++++++++++------------
 tests/generic/624.out |  15 ++----
 3 files changed, 101 insertions(+), 44 deletions(-)

diff --git a/common/verity b/common/verity
index b88e839b..77c257d3 100644
--- a/common/verity
+++ b/common/verity
@@ -263,6 +263,17 @@ _fsv_measure()
         $FSVERITY_PROG measure "$@" | awk '{print $1}'
 }
 
+_fsv_digest()
+{
+	local args=("$@")
+	# If the caller didn't explicitly specify a Merkle tree block size, then
+	# use FSV_BLOCK_SIZE.
+	if ! [[ " $*" =~ " --block-size" ]]; then
+		args+=("--block-size=$FSV_BLOCK_SIZE")
+	fi
+	$FSVERITY_PROG digest "${args[@]}" | awk '{print $1}'
+}
+
 _fsv_sign()
 {
 	local args=("$@")
diff --git a/tests/generic/624 b/tests/generic/624
index 7c447289..db4b6731 100755
--- a/tests/generic/624
+++ b/tests/generic/624
@@ -24,48 +24,99 @@ _cleanup()
 _supported_fs generic
 _require_scratch_verity
 _disable_fsverity_signatures
-# For the output of this test to always be the same, it has to use a specific
-# Merkle tree block size.
-if [ $FSV_BLOCK_SIZE != 4096 ]; then
-	_notrun "4096-byte verity block size not supported on this platform"
-fi
+fsv_orig_file=$SCRATCH_MNT/file
+fsv_file=$SCRATCH_MNT/file.fsv
 
 _scratch_mkfs_verity &>> $seqres.full
 _scratch_mount
-
-echo -e "\n# Creating a verity file"
-fsv_file=$SCRATCH_MNT/file
-# Always use the same file contents, so that the output of the test is always
-# the same.  Also use a file that is large enough to have multiple Merkle tree
-# levels, so that the test verifies that the blocks are returned in the expected
-# order.  A 1 MB file with SHA-256 and a Merkle tree block size of 4096 will
-# have 3 Merkle tree blocks (3*4096 bytes): two at level 0 and one at level 1.
-head -c 1000000 /dev/zero > $fsv_file
-merkle_tree_size=$((3 * FSV_BLOCK_SIZE))
-fsverity_descriptor_size=256
-_fsv_enable $fsv_file --salt=abcd
+_fsv_create_enable_file $fsv_file
 _require_fsverity_dump_metadata $fsv_file
-_fsv_measure $fsv_file
 
-echo -e "\n# Dumping Merkle tree"
-_fsv_dump_merkle_tree $fsv_file | sha256sum
+# Test FS_IOC_READ_VERITY_METADATA on a file that uses the given Merkle tree
+# block size.
+test_block_size()
+{
+	local block_size=$1
+	local digest_size=32 # assuming SHA-256
+	local i
+
+	# Create the file.  Make the file size big enough to result in multiple
+	# Merkle tree levels being needed.  The following expression computes a
+	# file size that needs 2 blocks at level 0, and thus 1 block at level 1.
+	local file_size=$((block_size * (2 * (block_size / digest_size))))
+	head -c $file_size /dev/zero > $fsv_orig_file
+	local tree_params=("--salt=abcd" "--block-size=$block_size")
+	cp $fsv_orig_file $fsv_file
+	_fsv_enable $fsv_file "${tree_params[@]}"
+
+	# Use the 'fsverity digest' command to compute the expected Merkle tree,
+	# descriptor, and file digest.
+	#
+	# Ideally we'd just hard-code expected values into the .out file and
+	# echo the actual values.  That doesn't quite work here, since all these
+	# values depend on the Merkle tree block size, and the Merkle tree block
+	# sizes that are supported (and thus get tested here) vary.  Therefore,
+	# we calculate the expected values in userspace with the help of
+	# 'fsverity digest', then do explicit comparisons with them.  This works
+	# fine as long as fsverity-utils and the kernel don't get broken in the
+	# same way, in which case generic/575 should detect the problem anyway.
+	local expected_file_digest=$(_fsv_digest $fsv_orig_file \
+		"${tree_params[@]}" \
+		--out-merkle-tree=$tmp.merkle_tree.expected \
+		--out-descriptor=$tmp.descriptor.expected)
+	local merkle_tree_size=$(_get_filesize $tmp.merkle_tree.expected)
+	local descriptor_size=$(_get_filesize $tmp.descriptor.expected)
 
-echo -e "\n# Dumping Merkle tree (in chunks)"
-# The above test may get the whole tree in one read, so also try reading it in
-# chunks.
-for (( i = 0; i < merkle_tree_size; i += 997 )); do
-	_fsv_dump_merkle_tree $fsv_file --offset=$i --length=997
-done | sha256sum
+	# 'fsverity measure' should return the expected file digest.
+	local actual_file_digest=$(_fsv_measure $fsv_file)
+	if [ "$actual_file_digest" != "$expected_file_digest" ]; then
+		echo "Measure returned $actual_file_digest but expected $expected_file_digest"
+	fi
 
-echo -e "\n# Dumping descriptor"
-# Note that the hash that is printed here should be the same hash that was
-# printed by _fsv_measure above.
-_fsv_dump_descriptor $fsv_file | sha256sum
+	# Test dumping the Merkle tree.
+	_fsv_dump_merkle_tree $fsv_file > $tmp.merkle_tree.actual
+	if ! cmp $tmp.merkle_tree.expected $tmp.merkle_tree.actual; then
+		echo "Dumped Merkle tree didn't match"
+	fi
+
+	# Test dumping the Merkle tree in chunks.
+	for (( i = 0; i < merkle_tree_size; i += 997 )); do
+		_fsv_dump_merkle_tree $fsv_file --offset=$i --length=997
+	done > $tmp.merkle_tree.actual
+	if ! cmp $tmp.merkle_tree.expected $tmp.merkle_tree.actual; then
+		echo "Dumped Merkle tree (in chunks) didn't match"
+	fi
+
+	# Test dumping the descriptor.
+	_fsv_dump_descriptor $fsv_file > $tmp.descriptor.actual
+	if ! cmp $tmp.descriptor.expected $tmp.descriptor.actual; then
+		echo "Dumped descriptor didn't match"
+	fi
+
+	# Test dumping the descriptor in chunks.
+	for (( i = 0; i < descriptor_size; i += 13 )); do
+		_fsv_dump_descriptor $fsv_file --offset=$i --length=13
+	done > $tmp.descriptor.actual
+	if ! cmp $tmp.descriptor.expected $tmp.descriptor.actual; then
+		echo "Dumped descriptor (in chunks) didn't match"
+	fi
+}
 
-echo -e "\n# Dumping descriptor (in chunks)"
-for (( i = 0; i < fsverity_descriptor_size; i += 13 )); do
-	_fsv_dump_descriptor $fsv_file --offset=$i --length=13
-done | sha256sum
+# Always test FSV_BLOCK_SIZE.  Also test some other block sizes if they happen
+# to be supported.
+_fsv_scratch_begin_subtest "Testing block_size=FSV_BLOCK_SIZE"
+test_block_size $FSV_BLOCK_SIZE
+for block_size in 1024 4096 16384 65536; do
+	_fsv_scratch_begin_subtest "Testing block_size=$block_size if supported"
+	if (( block_size == FSV_BLOCK_SIZE )); then
+		continue # Skip redundant test case.
+	fi
+	if ! _fsv_can_enable $fsv_file --block-size=$block_size; then
+		echo "block_size=$block_size is unsupported" >> $seqres.full
+		continue
+	fi
+	test_block_size $block_size
+done
 
 # success, all done
 status=0
diff --git a/tests/generic/624.out b/tests/generic/624.out
index 912826d3..0ea19ee5 100644
--- a/tests/generic/624.out
+++ b/tests/generic/624.out
@@ -1,16 +1,11 @@
 QA output created by 624
 
-# Creating a verity file
-sha256:11e4f886bf2d70a6ef3a8b6ce8e8c62c9e5d3263208b9f120ae46791f124be73
+# Testing block_size=FSV_BLOCK_SIZE
 
-# Dumping Merkle tree
-db88cdad554734cd648a1bfbb5be7f86646c54397847aab0b3f42a28829fed17  -
+# Testing block_size=1024 if supported
 
-# Dumping Merkle tree (in chunks)
-db88cdad554734cd648a1bfbb5be7f86646c54397847aab0b3f42a28829fed17  -
+# Testing block_size=4096 if supported
 
-# Dumping descriptor
-11e4f886bf2d70a6ef3a8b6ce8e8c62c9e5d3263208b9f120ae46791f124be73  -
+# Testing block_size=16384 if supported
 
-# Dumping descriptor (in chunks)
-11e4f886bf2d70a6ef3a8b6ce8e8c62c9e5d3263208b9f120ae46791f124be73  -
+# Testing block_size=65536 if supported
-- 
2.39.0


  parent reply	other threads:[~2022-12-29 23:35 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-29 23:32 [PATCH v3 00/10] xfstests: update verity tests for non-4K block and page size Eric Biggers
2022-12-29 23:32 ` [PATCH v3 01/10] common/verity: add and use _fsv_can_enable() Eric Biggers
2022-12-29 23:32 ` [PATCH v3 02/10] common/verity: set FSV_BLOCK_SIZE to an appropriate value Eric Biggers
2022-12-29 23:32 ` [PATCH v3 03/10] common/verity: use FSV_BLOCK_SIZE by default Eric Biggers
2022-12-29 23:32 ` [PATCH v3 04/10] common/verity: add _filter_fsverity_digest() Eric Biggers
2022-12-29 23:32 ` [PATCH v3 05/10] generic/572: support non-4K Merkle tree block size Eric Biggers
2022-12-29 23:32 ` [PATCH v3 06/10] generic/573: " Eric Biggers
2022-12-29 23:32 ` [PATCH v3 07/10] generic/577: " Eric Biggers
2022-12-29 23:32 ` [PATCH v3 08/10] generic/574: test multiple Merkle tree block sizes Eric Biggers
2022-12-29 23:32 ` Eric Biggers [this message]
2022-12-29 23:32 ` [PATCH v3 10/10] generic/575: test 1K Merkle tree block size Eric Biggers
2023-01-01 13:30 ` [PATCH v3 00/10] xfstests: update verity tests for non-4K block and page size Zorro Lang

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=20221229233222.119630-10-ebiggers@kernel.org \
    --to=ebiggers@kernel.org \
    --cc=fstests@vger.kernel.org \
    --cc=linux-fscrypt@vger.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.