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