blob: db4b6731031971e631b9064a91f23e9054c44cf2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0-only
# Copyright 2021 Google LLC
#
# FS QA Test No. 624
#
# Test retrieving the Merkle tree and fs-verity descriptor of a verity file
# using FS_IOC_READ_VERITY_METADATA.
#
. ./common/preamble
_begin_fstest auto quick verity
# Override the default cleanup function.
_cleanup()
{
cd /
_restore_fsverity_signatures
rm -f $tmp.*
}
. ./common/filter
. ./common/verity
_supported_fs generic
_require_scratch_verity
_disable_fsverity_signatures
fsv_orig_file=$SCRATCH_MNT/file
fsv_file=$SCRATCH_MNT/file.fsv
_scratch_mkfs_verity &>> $seqres.full
_scratch_mount
_fsv_create_enable_file $fsv_file
_require_fsverity_dump_metadata $fsv_file
# 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)
# '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
# 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
}
# 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
exit
|