From: Eric Biggers <ebiggers@kernel.org>
To: fstests@vger.kernel.org
Cc: linux-fscrypt@vger.kernel.org,
"Theodore Y . Ts'o" <tytso@mit.edu>,
Jaegeuk Kim <jaegeuk@kernel.org>,
Victor Hsieh <victorhsieh@google.com>
Subject: [PATCH 1/7] common/verity: add common functions for testing fs-verity
Date: Mon, 10 Dec 2018 14:21:36 -0800 [thread overview]
Message-ID: <20181210222142.222342-2-ebiggers@kernel.org> (raw)
In-Reply-To: <20181210222142.222342-1-ebiggers@kernel.org>
From: Eric Biggers <ebiggers@google.com>
Add common functions for setting up and testing fs-verity, a new feature
for read-only file-based authenticity protection. fs-verity will be
supported by ext4 and f2fs, and perhaps other filesystems later.
Running the fs-verity tests requires:
- A kernel with the fs-verity patches from
https://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt.git/log/
(should be merged in 4.21) and configured with CONFIG_FS_VERITY.
- The fsverity utility program, which can be installed from
https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/fsverity-utils.git/
- e2fsprogs v1.44.4-2 or later for ext4 tests, or f2fs-tools v1.11.0 or
later for f2fs tests.
See the file Documentation/filesystem/fsverity.rst in the kernel tree
for more information about fs-verity.
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
common/config | 1 +
common/verity | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 199 insertions(+)
create mode 100644 common/verity
diff --git a/common/config b/common/config
index a87cb4a2..b2160667 100644
--- a/common/config
+++ b/common/config
@@ -194,6 +194,7 @@ export GETCAP_PROG="$(type -P getcap)"
export CHECKBASHISMS_PROG="$(type -P checkbashisms)"
export XFS_INFO_PROG="$(type -P xfs_info)"
export DUPEREMOVE_PROG="$(type -P duperemove)"
+export FSVERITY_PROG="$(type -P fsverity)"
# use 'udevadm settle' or 'udevsettle' to wait for lv to be settled.
# newer systems have udevadm command but older systems like RHEL5 don't.
diff --git a/common/verity b/common/verity
new file mode 100644
index 00000000..4da63b69
--- /dev/null
+++ b/common/verity
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2018 Google LLC
+#
+# Functions for setting up and testing fs-verity
+
+FSV_BLOCK_SIZE=4096
+
+_require_scratch_verity()
+{
+ _require_scratch
+ _require_command "$FSVERITY_PROG" fsverity
+
+ if ! _scratch_mkfs_verity &>>$seqres.full; then
+ # ext4: need e2fsprogs v1.44.4-2 or later
+ # f2fs: need f2fs-tools v1.11.0 or later
+ _notrun "$FSTYP userspace tools don't support fs-verity"
+ fi
+
+ # Try to mount the filesystem. If this fails, then the filesystem is
+ # unaware of the fs-verity feature.
+ if ! _try_scratch_mount &>>$seqres.full; then
+ _notrun "kernel doesn't know about $FSTYP verity feature"
+ fi
+ _scratch_unmount
+
+ # The filesystem may be aware of fs-verity but have it disabled by
+ # CONFIG_FS_VERITY=n. Detect support via sysfs.
+ if [ ! -e /sys/fs/$FSTYP/features/verity ]; then
+ _notrun "kernel $FSTYP isn't configured with verity support"
+ fi
+
+ # fs-verity with block_size != PAGE_SIZE isn't implemented yet.
+ # ("block_size" here refers to the fs-verity block size, not to the
+ # filesystem's block size.)
+ if [ "$(getconf PAGE_SIZE)" != $FSV_BLOCK_SIZE ]; then
+ _notrun "verity not yet supported for PAGE_SIZE != $FSV_BLOCK_SIZE"
+ fi
+}
+
+_scratch_mkfs_verity()
+{
+ case $FSTYP in
+ ext4|f2fs)
+ _scratch_mkfs -O verity
+ ;;
+ *)
+ _notrun "No verity support for $FSTYP"
+ ;;
+ esac
+}
+
+_scratch_mkfs_encrypted_verity()
+{
+ case $FSTYP in
+ ext4)
+ _scratch_mkfs -O encrypt,verity
+ ;;
+ f2fs)
+ # f2fs-tools as of v1.11.0 doesn't allow comma-separated
+ # features with -O. Instead -O must be supplied multiple times.
+ _scratch_mkfs -O encrypt -O verity
+ ;;
+ *)
+ _notrun "$FSTYP not supported in _scratch_mkfs_encrypted_verity"
+ ;;
+ esac
+}
+
+_fsv_randstring()
+{
+ local nchars=$1
+
+ tr -d -C 0-9a-f < /dev/urandom | head -c "$nchars"
+}
+
+_fsv_begin_subtest()
+{
+ local msg=$1
+
+ rm -rf "${SCRATCH_MNT:?}"/*
+ echo -e "\n# $msg"
+}
+
+_fsv_setup()
+{
+ $FSVERITY_PROG setup "$@" | awk '/^File measurement: /{print $3}'
+}
+
+_fsv_enable()
+{
+ $FSVERITY_PROG enable "$@"
+}
+
+_fsv_measure()
+{
+ $FSVERITY_PROG measure "$@" | awk '{print $1}'
+}
+
+# Generate a file with verity metadata, but don't actually enable verity yet
+_fsv_create_setup_file()
+{
+ local file=$1
+
+ head -c $((FSV_BLOCK_SIZE * 2)) /dev/zero > "$file"
+ _fsv_setup "$file"
+}
+
+# Generate a file with verity metadata, then enable verity
+_fsv_create_enable_file()
+{
+ local file=$1
+
+ _fsv_create_setup_file "$file"
+ _fsv_enable "$file"
+}
+
+#
+# _fsv_corrupt_bytes - Write some bytes to a file, bypassing the filesystem
+#
+# Write the bytes sent on stdin to the given offset in the given file, but do so
+# by writing directly to the extents on the block device, with the filesystem
+# unmounted. This can be used to corrupt a verity file for testing purposes,
+# bypassing the restrictions imposed by the filesystem. On ext4 and f2fs this
+# can also write into the metadata region of a verity file.
+#
+# The file is assumed to be located on $SCRATCH_DEV.
+#
+_fsv_corrupt_bytes()
+{
+ local file=$1
+ local offset=$2
+ local lstarts=() # extent logical starts, in bytes
+ local pstarts=() # extent physical starts, in bytes
+ local lens=() # extent lengths, in bytes
+ local line
+ local cmd
+ local dd_cmds=()
+ local eidx=0
+
+ sync # Sync to avoid unwritten extents
+
+ cat > $tmp.bytes
+ local end=$(( offset + $(stat -c %s $tmp.bytes ) ))
+
+ # Get the list of extents that intersect the requested range
+ while read -r line; do \
+ local fields=($line)
+ local lstart=${fields[0]}
+ local lend=${fields[1]}
+ local pstart=${fields[2]}
+ local pend=${fields[3]}
+ local llen=$((lend + 1 - lstart))
+ local plen=$((pend + 1 - pstart))
+ if (( llen != plen )); then
+ _fail "Logical and physical extent lengths differ! $line"
+ fi
+ lstarts+=( $((lstart * 512)) )
+ pstarts+=( $((pstart * 512)) )
+ lens+=( $((llen * 512)) )
+ done < <($XFS_IO_PROG -r -c "fiemap $offset $((end - offset))" "$file" \
+ | grep -E '^[[:space:]]+[0-9]+:' \
+ | grep -v '\<hole\>' \
+ | sed -E 's/^[[:space:]]+[0-9]+://' \
+ | tr '][.:' ' ')
+
+ while (( offset < end )); do
+ # Find the next extent to write to
+ while true; do
+ if (( eidx >= ${#lstarts[@]} )); then
+ _fail "Extents ended before byte $offset"
+ fi
+ if (( offset < ${lstarts[$eidx]} )); then
+ _fail "Hole in file at byte $offset"
+ fi
+ local lend=$(( ${lstarts[$eidx]} + ${lens[$eidx]} ))
+ if (( offset < lend )); then
+ break
+ fi
+ (( eidx += 1 ))
+ done
+ # Add a command that writes to the next extent
+ local len=$((lend - offset))
+ local seek=$(( offset + ${pstarts[$eidx]} - ${lstarts[$eidx]} ))
+ if (( len > end - offset )); then
+ len=$((end - offset))
+ fi
+ dd_cmds+=("head -c $len | dd of=$SCRATCH_DEV oflag=seek_bytes seek=$seek status=none")
+ (( offset += len ))
+ done
+
+ # Execute the commands to write the data
+ _scratch_unmount
+ for cmd in "${dd_cmds[@]}"; do
+ eval "$cmd"
+ done < $tmp.bytes
+ sync # Sync to flush the block device's pagecache
+ _scratch_mount
+}
--
2.20.0.rc2.403.gdbc3b29805-goog
next prev parent reply other threads:[~2018-12-10 22:21 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-10 22:21 [PATCH 0/7] xfstests: add fs-verity tests Eric Biggers
2018-12-10 22:21 ` Eric Biggers [this message]
2018-12-15 14:38 ` [PATCH 1/7] common/verity: add common functions for testing fs-verity Eryu Guan
2018-12-10 22:21 ` [PATCH 2/7] generic: test general behavior of verity files Eric Biggers
2018-12-10 22:21 ` [PATCH 3/7] generic: test access controls on the fs-verity ioctls Eric Biggers
2018-12-15 14:40 ` Eryu Guan
2018-12-10 22:21 ` [PATCH 4/7] generic: test fs-verity descriptor validation Eric Biggers
2018-12-10 22:21 ` [PATCH 5/7] generic: test corrupting verity files Eric Biggers
2018-12-15 14:42 ` Eryu Guan
2018-12-10 22:21 ` [PATCH 6/7] generic: test that fs-verity is using the correct measurement values Eric Biggers
2018-12-10 22:21 ` [PATCH 7/7] generic: test using fs-verity and fscrypt simultaneously Eric Biggers
2018-12-11 13:52 ` [PATCH 0/7] xfstests: add fs-verity tests Christoph Hellwig
2018-12-11 17:29 ` Eric Biggers
2018-12-12 9:15 ` Christoph Hellwig
2018-12-12 3:00 ` Theodore Y. Ts'o
2018-12-15 14:28 ` Eryu Guan
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=20181210222142.222342-2-ebiggers@kernel.org \
--to=ebiggers@kernel.org \
--cc=fstests@vger.kernel.org \
--cc=jaegeuk@kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=victorhsieh@google.com \
/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;
as well as URLs for NNTP newsgroup(s).