From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
To: Boris Burkov <boris@bur.io>
Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org,
linux-btrfs@vger.kernel.org, kernel-team@fb.com,
Eric Biggers <ebiggers@google.com>,
Josef Bacik <josefbacik@toxicpanda.com>
Subject: Re: [PATCH v10 2/5] common/verity: support btrfs in generic fsverity tests
Date: Mon, 18 Jul 2022 14:45:01 -0400 [thread overview]
Message-ID: <da5f789371ea1b45826f8dd31189cb32@dorminy.me> (raw)
In-Reply-To: <727d2656f4c543fd8a50e0b4de3246d37d3e039d.1657916662.git.boris@bur.io>
On 2022-07-15 16:31, Boris Burkov wrote:
> generic/572-579 have tests for fsverity. Now that btrfs supports
> fsverity, make these tests function as well. For a majority of the
> tests
> that pass, simply adding the case to mkfs a btrfs filesystem with no
> extra options is sufficient.
>
> However, generic/574 has tests for corrupting the merkle tree itself.
> Since btrfs uses a different scheme from ext4 and f2fs for storing this
> data, the existing logic for corrupting it doesn't work out of the box.
> Adapt it to properly corrupt btrfs merkle items.
>
> 576 does not run because btrfs does not support transparent encryption.
>
> This test relies on the btrfs implementation of fsverity in the patch:
> btrfs: initial fsverity support
>
> and on btrfs-corrupt-block for corruption in the patches titled:
> btrfs-progs: corrupt generic item data with btrfs-corrupt-block
> btrfs-progs: expand corrupt_file_extent in btrfs-corrupt-block
>
> Signed-off-by: Boris Burkov <boris@bur.io>
> ---
> common/btrfs | 5 +++++
> common/config | 1 +
> common/verity | 32 ++++++++++++++++++++++++++++++++
> tests/generic/574 | 37 ++++++++++++++++++++++++++++++++++---
> tests/generic/574.out | 13 ++++---------
> 5 files changed, 76 insertions(+), 12 deletions(-)
>
> diff --git a/common/btrfs b/common/btrfs
> index 14ad890e..bd2639bf 100644
> --- a/common/btrfs
> +++ b/common/btrfs
> @@ -580,3 +580,8 @@ _btrfs_buffered_read_on_mirror()
> :
> done
> }
> +
> +_require_btrfs_corrupt_block()
> +{
> + _require_command "$BTRFS_CORRUPT_BLOCK_PROG" btrfs-corrupt-block
> +}
> diff --git a/common/config b/common/config
> index de3aba15..c30eec6d 100644
> --- a/common/config
> +++ b/common/config
> @@ -297,6 +297,7 @@ export BTRFS_UTIL_PROG=$(type -P btrfs)
> export BTRFS_SHOW_SUPER_PROG=$(type -P btrfs-show-super)
> export BTRFS_CONVERT_PROG=$(type -P btrfs-convert)
> export BTRFS_TUNE_PROG=$(type -P btrfstune)
> +export BTRFS_CORRUPT_BLOCK_PROG=$(type -P btrfs-corrupt-block)
> export XFS_FSR_PROG=$(type -P xfs_fsr)
> export MKFS_NFS_PROG="false"
> export MKFS_CIFS_PROG="false"
> diff --git a/common/verity b/common/verity
> index d58cad90..f9ccf2ff 100644
> --- a/common/verity
> +++ b/common/verity
> @@ -3,6 +3,17 @@
> #
> # Functions for setting up and testing fs-verity
>
> +. common/btrfs
Only a tiny thing: do you need this include? I think all the
btrfs-specific stuff you're adding is behind a FSTYP == btrfs check, so
I think you could get away without having the include?
> +# btrfs will return IO errors on corrupted data with or without
> fs-verity.
> +# to really test fs-verity, use nodatasum.
> +if [ "$FSTYP" == "btrfs" ]; then
> + if [ -z $MOUNT_OPTIONS ]; then
> + export MOUNT_OPTIONS="-o nodatasum"
> + else
> + export MOUNT_OPTIONS+=" -o nodatasum"
> + fi
> +fi
> +
> _require_scratch_verity()
> {
> _require_scratch
> @@ -145,6 +156,9 @@ _require_fsverity_dump_metadata()
> _require_fsverity_corruption()
> {
> _require_xfs_io_command "fiemap"
> + if [ $FSTYP == "btrfs" ]; then
> + _require_btrfs_corrupt_block
> + fi
> }
>
> _scratch_mkfs_verity()
> @@ -153,6 +167,9 @@ _scratch_mkfs_verity()
> ext4|f2fs)
> _scratch_mkfs -O verity
> ;;
> + btrfs)
> + _scratch_mkfs
> + ;;
> *)
> _notrun "No verity support for $FSTYP"
> ;;
> @@ -314,6 +331,21 @@ _fsv_scratch_corrupt_merkle_tree()
> (( offset += ($(_get_filesize $file) + 65535) & ~65535 ))
> _fsv_scratch_corrupt_bytes $file $offset
> ;;
> + btrfs)
> + local ino=$(stat -c '%i' $file)
> + _scratch_unmount
> + local byte=""
> + while read -n 1 byte; do
> + local ascii=$(printf "%d" "'$byte'")
> + # This command will find a Merkle tree item for the inode (-I
> $ino,37,0)
> + # in the default filesystem tree (-r 5) and corrupt one byte (-b 1)
> at
> + # $offset (-o $offset) with the ascii representation of the byte we
> read
> + # (-v $ascii)
> + $BTRFS_CORRUPT_BLOCK_PROG -r 5 -I $ino,37,0 -v $ascii -o $offset
> -b 1 $SCRATCH_DEV
> + (( offset += 1 ))
> + done
> + _scratch_mount
> + ;;
> *)
> _fail "_fsv_scratch_corrupt_merkle_tree() unimplemented on $FSTYP"
> ;;
> diff --git a/tests/generic/574 b/tests/generic/574
> index 17fdea52..5ba4be7e 100755
> --- a/tests/generic/574
> +++ b/tests/generic/574
> @@ -126,6 +126,39 @@ corruption_test()
> fi
> }
>
> +# Reading the last block of the file with mmap is tricky, so we need
> to be
> +# a bit careful. Some filesystems read the last block in full, while
> others
> +# return zeros in the last block past EOF, regardless of the contents
> on
> +# disk. In the former, corruption should be detected and result in
> SIGBUS,
> +# while in the latter we would expect zeros past EOF, but no error.
> +corrupt_eof_block_test() {
> + local file_len=$1
> + local zap_len=$2
> + local page_aligned_eof=$(round_up_to_page_boundary $file_len)
> + _fsv_scratch_begin_subtest "Corruption test: EOF block"
> + setup_zeroed_file $file_len false
> + cmp $fsv_file $fsv_orig_file
> + echo "Corrupting bytes..."
> + head -c $zap_len /dev/zero | tr '\0' X \
> + | _fsv_scratch_corrupt_bytes $fsv_file $file_len
> +
> + echo "Reading eof block via mmap into a temporary file..."
> + bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
> + -c 'mmap -r 0 $page_aligned_eof' \
> + -c 'mread -v $file_len $zap_len'" \
> + |& filter_sigbus >$tmp.eof_block_read 2>&1
> +
> + head -c $file_len /dev/zero > $tmp.zero_cmp_file
> + $XFS_IO_PROG -r $tmp.zero_cmp_file \
> + -c "mmap -r 0 $page_aligned_eof" \
> + -c "mread -v $file_len $zap_len" >$tmp.eof_zero_read
> +
> + echo "Checking for SIGBUS or zeros..."
> + <$tmp.eof_block_read grep -q -e '^Bus error$' \
> + || diff $tmp.eof_block_read $tmp.eof_zero_read \
> + && echo "OK"
> +}
> +
> # Note: these tests just overwrite some bytes without checking their
> original
> # values. Therefore, make sure to overwrite at least 5 or so bytes,
> to make it
> # nearly guaranteed that there will be a change -- even when the test
> file is
> @@ -136,9 +169,7 @@ corruption_test 131072 4091 5
> corruption_test 131072 65536 65536
> corruption_test 131072 131067 5
>
> -# Non-zeroed bytes in the final partial block beyond EOF should cause
> reads to
> -# fail too. Such bytes would be visible via mmap().
> -corruption_test 130999 131000 72
> +corrupt_eof_block_test 130999 72
>
> # Merkle tree corruption.
> corruption_test 200000 100 10 true
> diff --git a/tests/generic/574.out b/tests/generic/574.out
> index 3c08d3e8..d40d1263 100644
> --- a/tests/generic/574.out
> +++ b/tests/generic/574.out
> @@ -56,17 +56,12 @@ Bus error
> Validating corruption (reading just corrupted part via mmap)...
> Bus error
>
> -# Corruption test: file_len=130999 zap_offset=131000 zap_len=72
> +# Corruption test: EOF block
> f5cca0d7fbb8b02bc6118a9954d5d306 SCRATCH_MNT/file.fsv
> Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> -Validating corruption (reading just corrupted part via mmap)...
> -Bus error
> +Reading eof block via mmap into a temporary file...
> +Checking for SIGBUS or zeros...
> +OK
>
> # Corruption test: file_len=200000 zap_offset=100 (in Merkle tree)
> zap_len=10
> 4a1e4325031b13f933ac4f1db9ecb63f SCRATCH_MNT/file.fsv
next prev parent reply other threads:[~2022-07-18 18:45 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-15 20:31 [PATCH v10 0/5] tests for btrfs fsverity Boris Burkov
2022-07-15 20:31 ` [PATCH v10 1/5] common/verity: require corruption functionality Boris Burkov
2022-07-15 20:31 ` [PATCH v10 2/5] common/verity: support btrfs in generic fsverity tests Boris Burkov
2022-07-18 18:45 ` Sweet Tea Dorminy [this message]
2022-07-15 20:31 ` [PATCH v10 3/5] btrfs: test btrfs specific fsverity corruption Boris Burkov
2022-07-15 20:31 ` [PATCH v10 4/5] btrfs: test verity orphans with dmlogwrites Boris Burkov
2022-07-15 20:31 ` [PATCH v10 5/5] generic: test fs-verity EFBIG scenarios Boris Burkov
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=da5f789371ea1b45826f8dd31189cb32@dorminy.me \
--to=sweettea-kernel@dorminy.me \
--cc=boris@bur.io \
--cc=ebiggers@google.com \
--cc=fstests@vger.kernel.org \
--cc=josefbacik@toxicpanda.com \
--cc=kernel-team@fb.com \
--cc=linux-btrfs@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox