mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
11d3da6a7f
There are some testcases use below two kind of commands to get file
size, generalize the second way as global function _get_filesize()
to simply codes.
1. ls -l $1 | $AWK_PROG '{print $5}'
2. stat -c %s $1
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Reviewed-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
245 lines
6.4 KiB
Plaintext
245 lines
6.4 KiB
Plaintext
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright 2018 Google LLC
|
|
#
|
|
# Functions for setting up and testing fs-verity
|
|
|
|
_require_scratch_verity()
|
|
{
|
|
_require_scratch
|
|
_require_command "$FSVERITY_PROG" fsverity
|
|
|
|
if ! _scratch_mkfs_verity &>>$seqres.full; then
|
|
# ext4: need e2fsprogs v1.44.5 or later (but actually v1.45.2+
|
|
# is needed for some tests to pass, due to an e2fsck bug)
|
|
# 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 either the kernel
|
|
# isn't aware of fs-verity, or the mkfs options were not compatible with
|
|
# verity (e.g. ext4 with block size != PAGE_SIZE).
|
|
if ! _try_scratch_mount &>>$seqres.full; then
|
|
_notrun "kernel is unaware of $FSTYP verity feature," \
|
|
"or mkfs options are not compatible with verity"
|
|
fi
|
|
|
|
# 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
|
|
|
|
# The filesystem may have fs-verity enabled but not actually usable by
|
|
# default. E.g., ext4 only supports verity on extent-based files, so it
|
|
# doesn't work on ext3-style filesystems. So, try actually using it.
|
|
echo foo > $SCRATCH_MNT/tmpfile
|
|
_disable_fsverity_signatures
|
|
if ! _fsv_enable $SCRATCH_MNT/tmpfile; then
|
|
_restore_fsverity_signatures
|
|
_notrun "$FSTYP verity isn't usable by default with these mkfs options"
|
|
fi
|
|
_restore_fsverity_signatures
|
|
rm -f $SCRATCH_MNT/tmpfile
|
|
|
|
_scratch_unmount
|
|
|
|
# Merkle tree block size. Currently all filesystems only support
|
|
# PAGE_SIZE for this. This is also the default for 'fsverity enable'.
|
|
FSV_BLOCK_SIZE=$(get_page_size)
|
|
}
|
|
|
|
# Check for CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y.
|
|
_require_fsverity_builtin_signatures()
|
|
{
|
|
if [ ! -e /proc/sys/fs/verity/require_signatures ]; then
|
|
_notrun "kernel doesn't support fs-verity builtin signatures"
|
|
fi
|
|
}
|
|
|
|
# Disable mandatory signatures for fs-verity files, if they are supported.
|
|
_disable_fsverity_signatures()
|
|
{
|
|
if [ -e /proc/sys/fs/verity/require_signatures ]; then
|
|
if [ -z "$FSVERITY_SIG_CTL_ORIG" ]; then
|
|
FSVERITY_SIG_CTL_ORIG=$(</proc/sys/fs/verity/require_signatures)
|
|
fi
|
|
echo 0 > /proc/sys/fs/verity/require_signatures
|
|
fi
|
|
}
|
|
|
|
# Enable mandatory signatures for fs-verity files.
|
|
# This assumes that _require_fsverity_builtin_signatures() was called.
|
|
_enable_fsverity_signatures()
|
|
{
|
|
if [ -z "$FSVERITY_SIG_CTL_ORIG" ]; then
|
|
FSVERITY_SIG_CTL_ORIG=$(</proc/sys/fs/verity/require_signatures)
|
|
fi
|
|
echo 1 > /proc/sys/fs/verity/require_signatures
|
|
}
|
|
|
|
# Restore the original signature verification setting.
|
|
_restore_fsverity_signatures()
|
|
{
|
|
if [ -n "$FSVERITY_SIG_CTL_ORIG" ]; then
|
|
echo "$FSVERITY_SIG_CTL_ORIG" > /proc/sys/fs/verity/require_signatures
|
|
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_scratch_begin_subtest()
|
|
{
|
|
local msg=$1
|
|
|
|
rm -rf "${SCRATCH_MNT:?}"/*
|
|
echo -e "\n# $msg"
|
|
}
|
|
|
|
_fsv_enable()
|
|
{
|
|
$FSVERITY_PROG enable "$@"
|
|
}
|
|
|
|
_fsv_measure()
|
|
{
|
|
$FSVERITY_PROG measure "$@" | awk '{print $1}'
|
|
}
|
|
|
|
_fsv_sign()
|
|
{
|
|
$FSVERITY_PROG sign "$@"
|
|
}
|
|
|
|
# Generate a file, then enable verity on it.
|
|
_fsv_create_enable_file()
|
|
{
|
|
local file=$1
|
|
shift
|
|
|
|
head -c $((FSV_BLOCK_SIZE * 2)) /dev/zero > "$file"
|
|
_fsv_enable "$file" "$@"
|
|
}
|
|
|
|
_fsv_have_hash_algorithm()
|
|
{
|
|
local hash_alg=$1
|
|
local test_file=$2
|
|
|
|
rm -f $test_file
|
|
head -c 4096 /dev/zero > $test_file
|
|
if ! _fsv_enable --hash-alg=$hash_alg $test_file &>> $seqres.full; then
|
|
# no kernel support
|
|
return 1
|
|
fi
|
|
rm -f $test_file
|
|
return 0
|
|
}
|
|
|
|
#
|
|
# _fsv_scratch_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.
|
|
#
|
|
# The file is assumed to be located on $SCRATCH_DEV.
|
|
#
|
|
_fsv_scratch_corrupt_bytes()
|
|
{
|
|
local file=$1
|
|
local offset=$2
|
|
local lstart lend pstart pend
|
|
local dd_cmds=()
|
|
local cmd
|
|
|
|
sync # Sync to avoid unwritten extents
|
|
|
|
cat > $tmp.bytes
|
|
local end=$(( offset + $(_get_filesize $tmp.bytes ) ))
|
|
|
|
# For each extent that intersects the requested range in order, add a
|
|
# command that writes the next part of the data to that extent.
|
|
while read -r lstart lend pstart pend; do
|
|
lstart=$((lstart * 512))
|
|
lend=$(((lend + 1) * 512))
|
|
pstart=$((pstart * 512))
|
|
pend=$(((pend + 1) * 512))
|
|
|
|
if (( lend - lstart != pend - pstart )); then
|
|
_fail "Logical and physical extent lengths differ for file '$file'"
|
|
elif (( offset < lstart )); then
|
|
_fail "Hole in file '$file' at byte $offset. Next extent begins at byte $lstart"
|
|
elif (( offset < lend )); then
|
|
local len=$((lend - offset))
|
|
local seek=$((pstart + (offset - lstart)))
|
|
dd_cmds+=("head -c $len | dd of=$SCRATCH_DEV oflag=seek_bytes seek=$seek status=none")
|
|
(( offset += len ))
|
|
fi
|
|
done < <($XFS_IO_PROG -r -c "fiemap $offset $((end - offset))" "$file" \
|
|
| _filter_xfs_io_fiemap)
|
|
|
|
if (( offset < end )); then
|
|
_fail "Extents of file '$file' ended at byte $offset, but needed until $end"
|
|
fi
|
|
|
|
# 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
|
|
}
|
|
|
|
#
|
|
# _fsv_scratch_corrupt_merkle_tree - Corrupt a file's Merkle tree
|
|
#
|
|
# Like _fsv_scratch_corrupt_bytes(), but this corrupts the file's fs-verity
|
|
# Merkle tree. The offset is given as a byte offset into the Merkle tree.
|
|
#
|
|
_fsv_scratch_corrupt_merkle_tree()
|
|
{
|
|
local file=$1
|
|
local offset=$2
|
|
|
|
case $FSTYP in
|
|
ext4|f2fs)
|
|
# ext4 and f2fs store the Merkle tree after the file contents
|
|
# itself, starting at the next 65536-byte aligned boundary.
|
|
(( offset += ($(_get_filesize $file) + 65535) & ~65535 ))
|
|
_fsv_scratch_corrupt_bytes $file $offset
|
|
;;
|
|
*)
|
|
_fail "_fsv_scratch_corrupt_merkle_tree() unimplemented on $FSTYP"
|
|
;;
|
|
esac
|
|
}
|