382c4947478589ddabe731c0d7182dbedf70c7ec
[xfstests-dev.git] / tests / generic / 572
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright 2018 Google LLC
4 #
5 # FS QA Test generic/572
6 #
7 # This is a basic fs-verity test which verifies:
8 #
9 # - conditions for enabling verity
10 # - verity files have correct contents and size
11 # - can't change contents of verity files, but can change metadata
12 # - can retrieve a verity file's measurement via FS_IOC_MEASURE_VERITY
13 #
14 seq=`basename $0`
15 seqres=$RESULT_DIR/$seq
16 echo "QA output created by $seq"
17
18 here=`pwd`
19 tmp=/tmp/$$
20 status=1        # failure is the default!
21 trap "_cleanup; exit \$status" 0 1 2 3 15
22
23 _cleanup()
24 {
25         cd /
26         rm -f $tmp.*
27 }
28
29 # get standard environment, filters and checks
30 . ./common/rc
31 . ./common/filter
32 . ./common/verity
33
34 # remove previous $seqres.full before test
35 rm -f $seqres.full
36
37 # real QA test starts here
38 _supported_fs generic
39 _supported_os Linux
40 _require_scratch_verity
41
42 _scratch_mkfs_verity &>> $seqres.full
43 _scratch_mount
44 fsv_orig_file=$SCRATCH_MNT/file
45 fsv_file=$SCRATCH_MNT/file.fsv
46
47 verify_data_readable()
48 {
49         local file=$1
50
51         md5sum $file > /dev/null
52 }
53
54 verify_data_unreadable()
55 {
56         local file=$1
57
58         # try both reading just the first data block, and reading until EOF
59         head -c $FSV_BLOCK_SIZE $file 2>&1 >/dev/null | _filter_scratch
60         md5sum $file |& _filter_scratch
61 }
62
63 _fsv_scratch_begin_subtest "Enabling verity on file with verity already enabled fails with EEXIST"
64 _fsv_create_enable_file $fsv_file
65 echo "(trying again)"
66 _fsv_enable $fsv_file |& _filter_scratch
67
68 _fsv_scratch_begin_subtest "Enabling verity with invalid hash algorithm fails with EINVAL"
69 _fsv_create_enable_file $fsv_file --hash-alg=257 |& _filter_scratch
70 verify_data_readable $fsv_file
71
72 _fsv_scratch_begin_subtest "Enabling verity with invalid block size fails with EINVAL"
73 _fsv_create_enable_file $fsv_file --block-size=1 |& _filter_scratch
74 verify_data_readable $fsv_file
75
76 _fsv_scratch_begin_subtest "Enabling verity on directory fails with EISDIR"
77 mkdir $SCRATCH_MNT/dir
78 _fsv_enable $SCRATCH_MNT/dir |& _filter_scratch
79
80 _fsv_scratch_begin_subtest "Enabling verity with too-long salt fails with EMSGSIZE"
81 _fsv_create_enable_file $fsv_file --salt=$(perl -e 'print "A" x 1000') |& _filter_scratch
82 verify_data_readable $fsv_file
83
84 _fsv_scratch_begin_subtest "Enabling verity on file on read-only filesystem fails with EROFS"
85 echo foo > $fsv_file
86 _scratch_remount ro
87 _fsv_enable $fsv_file |& _filter_scratch
88 _scratch_remount rw
89
90 _fsv_scratch_begin_subtest "Enabling verity on file open for writing fails with ETXTBSY"
91 echo foo > $fsv_file
92 exec 3<> $fsv_file
93 _fsv_enable $fsv_file |& _filter_scratch
94 exec 3<&-
95 verify_data_readable $fsv_file
96
97 _fsv_scratch_begin_subtest "Enabling verity can be interrupted"
98 dd if=/dev/zero of=$fsv_file bs=1 count=0 seek=$((1 << 34)) status=none
99 start_time=$(date +%s)
100 $FSVERITY_PROG enable $fsv_file &
101 sleep 0.5
102 kill %1
103 wait
104 elapsed=$(( $(date +%s) - start_time ))
105 if (( elapsed > 5 )); then
106         echo "Failed to interrupt FS_IOC_ENABLE_VERITY ($elapsed seconds elapsed)"
107 fi
108
109 _fsv_scratch_begin_subtest "Enabling verity on file with verity already being enabled fails with EBUSY"
110 dd if=/dev/zero of=$fsv_file bs=1 count=0 seek=$((1 << 34)) status=none
111 start_time=$(date +%s)
112 $FSVERITY_PROG enable $fsv_file &
113 sleep 0.5
114 _fsv_enable $fsv_file |& _filter_scratch
115 kill %1
116 wait
117
118 _fsv_scratch_begin_subtest "verity file can't be opened for writing"
119 _fsv_create_enable_file $fsv_file >> $seqres.full
120 echo "* reading"
121 $XFS_IO_PROG -r $fsv_file -c ''
122 echo "* xfs_io writing, should be O_RDWR"
123 $XFS_IO_PROG $fsv_file -c '' |& _filter_scratch
124 echo "* bash >>, should be O_APPEND"
125 bash -c "echo >> $fsv_file" |& _filter_scratch
126 echo "* bash >, should be O_WRONLY|O_CREAT|O_TRUNC"
127 bash -c "echo > $fsv_file" |& _filter_scratch
128
129 _fsv_scratch_begin_subtest "verity file can be read"
130 _fsv_create_enable_file $fsv_file >> $seqres.full
131 verify_data_readable $fsv_file
132
133 _fsv_scratch_begin_subtest "verity file can be measured"
134 _fsv_create_enable_file $fsv_file >> $seqres.full
135 _fsv_measure $fsv_file
136
137 _fsv_scratch_begin_subtest "verity file can be renamed"
138 _fsv_create_enable_file $fsv_file
139 mv $fsv_file $fsv_file.newname
140
141 _fsv_scratch_begin_subtest "verity file can be unlinked"
142 _fsv_create_enable_file $fsv_file
143 rm $fsv_file
144
145 _fsv_scratch_begin_subtest "verity file can be linked to"
146 _fsv_create_enable_file $fsv_file
147 ln $fsv_file $fsv_file.newname
148
149 _fsv_scratch_begin_subtest "verity file can be chmodded"
150 _fsv_create_enable_file $fsv_file
151 chmod 777 $fsv_file
152 chmod 444 $fsv_file
153
154 _fsv_scratch_begin_subtest "verity file can be chowned"
155 _fsv_create_enable_file $fsv_file
156 chown 1:1 $fsv_file
157 chown 0:0 $fsv_file
158
159 _fsv_scratch_begin_subtest "verity file has correct contents and size"
160 head -c 100000 /dev/urandom > $fsv_orig_file
161 cp $fsv_orig_file $fsv_file
162 _fsv_enable $fsv_file >> $seqres.full
163 cmp $fsv_file $fsv_orig_file
164 stat -c %s $fsv_file
165 _scratch_cycle_mount
166 cmp $fsv_file $fsv_orig_file
167 stat -c %s $fsv_file
168
169 _fsv_scratch_begin_subtest "Trying to measure non-verity file fails with ENODATA"
170 echo foo > $fsv_file
171 _fsv_measure $fsv_file |& _filter_scratch
172 verify_data_readable $fsv_file
173
174 # Test files <= 1 block in size.  These are a bit of a special case since there
175 # are no hash blocks; the root hash is calculated directly over the data block.
176 for size in 1 $((FSV_BLOCK_SIZE - 1)) $FSV_BLOCK_SIZE; do
177         _fsv_scratch_begin_subtest "verity on $size-byte file"
178         head -c $size /dev/urandom > $fsv_orig_file
179         cp $fsv_orig_file $fsv_file
180         _fsv_enable $fsv_file
181         cmp $fsv_orig_file $fsv_file && echo "Files matched"
182         rm -f $fsv_file
183 done
184
185 _fsv_scratch_begin_subtest "verity on 100M file (multiple levels in hash tree)"
186 head -c 100000000 /dev/urandom > $fsv_orig_file
187 cp $fsv_orig_file $fsv_file
188 _fsv_enable $fsv_file
189 cmp $fsv_orig_file $fsv_file && echo "Files matched"
190
191 _fsv_scratch_begin_subtest "verity on sparse file"
192 dd if=/dev/zero of=$fsv_orig_file bs=1 count=1 seek=1000000 status=none
193 cp $fsv_orig_file $fsv_file
194 _fsv_enable $fsv_file
195 cmp $fsv_orig_file $fsv_file && echo "Files matched"
196
197 # success, all done
198 status=0
199 exit