Re: [PATCH v8 3/5] btrfs: test btrfs specific fsverity corruption

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



On Sun, Apr 10, 2022 at 10:53:04PM +0800, Eryu Guan wrote:
> On Wed, Mar 16, 2022 at 01:25:13PM -0700, Boris Burkov wrote:
> > There are some btrfs specific fsverity scenarios that don't map
> > neatly onto the tests in generic/574 like holes, inline extents,
> > and preallocated extents. Cover those in a btrfs specific test.
> > 
> > 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@xxxxxx>
> > ---
> >  tests/btrfs/290     | 168 ++++++++++++++++++++++++++++++++++++++++++++
> >  tests/btrfs/290.out |  25 +++++++
> >  2 files changed, 193 insertions(+)
> >  create mode 100755 tests/btrfs/290
> >  create mode 100644 tests/btrfs/290.out
> > 
> > diff --git a/tests/btrfs/290 b/tests/btrfs/290
> > new file mode 100755
> > index 00000000..f9acd55a
> > --- /dev/null
> > +++ b/tests/btrfs/290
> > @@ -0,0 +1,168 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (C) 2021 Facebook, Inc. All Rights Reserved.
> 
> I noticed that all patches have 2021 in copyright statement, should be
> updated to 2022?

Oops, good catch. I will resend with the right copyright statement along
with any changes from review on the btrfs tests.

Thanks for taking a look,
Boris

> 
> And I'd like btrfs folks to help review these 2 btrfs specific tests.
> 
> Thanks,
> Eryu
> 
> > +#
> > +# FS QA Test 290
> > +#
> > +# Test btrfs support for fsverity.
> > +# This test extends the generic fsverity testing by corrupting inline extents,
> > +# preallocated extents, holes, and the Merkle descriptor in a btrfs-aware way.
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick verity
> > +
> > +# Import common functions.
> > +. ./common/filter
> > +. ./common/verity
> > +
> > +# real QA test starts here
> > +_supported_fs btrfs
> > +_require_scratch_verity
> > +_require_scratch_nocheck
> > +_require_odirect
> > +_require_xfs_io_command "falloc"
> > +_require_xfs_io_command "pread"
> > +_require_xfs_io_command "pwrite"
> > +_require_btrfs_corrupt_block
> > +
> > +get_ino() {
> > +	local file=$1
> > +	stat -c "%i" $file
> > +}
> > +
> > +validate() {
> > +	local f=$1
> > +	local sz=$(_get_filesize $f)
> > +	# buffered io
> > +	echo $(basename $f)
> > +	$XFS_IO_PROG -rc "pread -q 0 $sz" $f 2>&1 | _filter_scratch
> > +	# direct io
> > +	$XFS_IO_PROG -rdc "pread -q 0 $sz" $f 2>&1 | _filter_scratch
> > +}
> > +
> > +# corrupt the data portion of an inline extent
> > +corrupt_inline() {
> > +	local f=$SCRATCH_MNT/inl
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 42" $f
> > +	local ino=$(get_ino $f)
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# inline data starts at disk_bytenr
> > +	# overwrite the first u64 with random bogus junk
> > +	$BTRFS_CORRUPT_BLOCK_PROG -i $ino -x 0 -f disk_bytenr $SCRATCH_DEV > /dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# preallocate a file, then corrupt it by changing it to a regular file
> > +corrupt_prealloc_to_reg() {
> > +	local f=$SCRATCH_MNT/prealloc
> > +	$XFS_IO_PROG -fc "falloc 0 12k" $f
> > +	local ino=$(get_ino $f)
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# set extent type from prealloc (2) to reg (1)
> > +	$BTRFS_CORRUPT_BLOCK_PROG -i $ino -x 0 -f type -v 1 $SCRATCH_DEV >/dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# corrupt a regular file by changing the type to preallocated
> > +corrupt_reg_to_prealloc() {
> > +	local f=$SCRATCH_MNT/reg
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 12288" $f
> > +	local ino=$(get_ino $f)
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# set type from reg (1) to prealloc (2)
> > +	$BTRFS_CORRUPT_BLOCK_PROG -i $ino -x 0 -f type -v 2 $SCRATCH_DEV >/dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# corrupt a file by punching a hole
> > +corrupt_punch_hole() {
> > +	local f=$SCRATCH_MNT/punch
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 12288" $f
> > +	local ino=$(get_ino $f)
> > +	# make a new extent in the middle, sync so the writes don't coalesce
> > +	$XFS_IO_PROG -c sync $SCRATCH_MNT
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x59 4096 4096" $f
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# change disk_bytenr to 0, representing a hole
> > +	$BTRFS_CORRUPT_BLOCK_PROG -i $ino -x 4096 -f disk_bytenr -v 0 $SCRATCH_DEV > /dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# plug hole
> > +corrupt_plug_hole() {
> > +	local f=$SCRATCH_MNT/plug
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 12288" $f
> > +	local ino=$(get_ino $f)
> > +	$XFS_IO_PROG -fc "falloc 4k 4k" $f
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# change disk_bytenr to some value, plugging the hole
> > +	$BTRFS_CORRUPT_BLOCK_PROG -i $ino -x 4096 -f disk_bytenr -v 13639680 $SCRATCH_DEV > /dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# corrupt the fsverity descriptor item indiscriminately (causes EINVAL)
> > +corrupt_verity_descriptor() {
> > +	local f=$SCRATCH_MNT/desc
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 12288" $f
> > +	local ino=$(get_ino $f)
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# key for the descriptor item is <inode, BTRFS_VERITY_DESC_ITEM_KEY, 1>,
> > +	# 88 is X. So we write 5 Xs to the start of the descriptor
> > +	$BTRFS_CORRUPT_BLOCK_PROG -r 5 -I $ino,36,1 -v 88 -o 0 -b 5 $SCRATCH_DEV > /dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# specifically target the root hash in the descriptor (causes EIO)
> > +corrupt_root_hash() {
> > +	local f=$SCRATCH_MNT/roothash
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 12288" $f
> > +	local ino=$(get_ino $f)
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	$BTRFS_CORRUPT_BLOCK_PROG -r 5 -I $ino,36,1 -v 88 -o 16 -b 1 $SCRATCH_DEV > /dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# corrupt the Merkle tree data itself
> > +corrupt_merkle_tree() {
> > +	local f=$SCRATCH_MNT/merkle
> > +	$XFS_IO_PROG -fc "pwrite -q -S 0x58 0 12288" $f
> > +	local ino=$(get_ino $f)
> > +	_fsv_enable $f
> > +	_scratch_unmount
> > +	# key for the descriptor item is <inode, BTRFS_VERITY_MERKLE_ITEM_KEY, 0>,
> > +	# 88 is X. So we write 5 Xs to somewhere in the middle of the first
> > +	# merkle item
> > +	$BTRFS_CORRUPT_BLOCK_PROG -r 5 -I $ino,37,0 -v 88 -o 100 -b 5 $SCRATCH_DEV > /dev/null 2>&1
> > +	_scratch_mount
> > +	validate $f
> > +}
> > +
> > +# real QA test starts here
> > +_scratch_mkfs >/dev/null
> > +_scratch_mount
> > +
> > +corrupt_inline
> > +corrupt_prealloc_to_reg
> > +corrupt_reg_to_prealloc
> > +corrupt_punch_hole
> > +corrupt_plug_hole
> > +corrupt_verity_descriptor
> > +corrupt_root_hash
> > +corrupt_merkle_tree
> > +
> > +status=0
> > +exit
> > diff --git a/tests/btrfs/290.out b/tests/btrfs/290.out
> > new file mode 100644
> > index 00000000..056b114b
> > --- /dev/null
> > +++ b/tests/btrfs/290.out
> > @@ -0,0 +1,25 @@
> > +QA output created by 290
> > +inl
> > +pread: Input/output error
> > +pread: Input/output error
> > +prealloc
> > +pread: Input/output error
> > +pread: Input/output error
> > +reg
> > +pread: Input/output error
> > +pread: Input/output error
> > +punch
> > +pread: Input/output error
> > +pread: Input/output error
> > +plug
> > +pread: Input/output error
> > +pread: Input/output error
> > +desc
> > +SCRATCH_MNT/desc: Invalid argument
> > +SCRATCH_MNT/desc: Invalid argument
> > +roothash
> > +pread: Input/output error
> > +pread: Input/output error
> > +merkle
> > +pread: Input/output error
> > +pread: Input/output error
> > -- 
> > 2.31.0



[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux