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