generic: test for file fsync after moving it to a new parent directory
[xfstests-dev.git] / tests / generic / 421
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2017 Google, Inc.  All Rights Reserved.
4 #
5 # FS QA Test generic/421
6 #
7 # Test revoking an encryption key during concurrent I/O.  Regression test for
8 # 1b53cf9815bb ("fscrypt: remove broken support for detecting keyring key
9 # revocation").
10 #
11 seq=`basename $0`
12 seqres=$RESULT_DIR/$seq
13 echo "QA output created by $seq"
14
15 here=`pwd`
16 tmp=/tmp/$$
17 status=1        # failure is the default!
18 trap "_cleanup; exit \$status" 0 1 2 3 15
19
20 _cleanup()
21 {
22         cd /
23         rm -f $tmp.*
24 }
25
26 # get standard environment, filters and checks
27 . ./common/rc
28 . ./common/filter
29 . ./common/encrypt
30
31 # remove previous $seqres.full before test
32 rm -f $seqres.full
33
34 # real QA test starts here
35 _supported_fs generic
36 _supported_os Linux
37 _require_scratch_encryption
38 _require_xfs_io_command "set_encpolicy"
39 _require_command "$KEYCTL_PROG" keyctl
40
41 _new_session_keyring
42 _scratch_mkfs_encrypted &>> $seqres.full
43 _scratch_mount
44
45 dir=$SCRATCH_MNT/encrypted_dir
46 file=$dir/file
47
48 # 4 processes, 2 MB per process
49 nproc=4
50 slice=2
51
52 # Create an encrypted file and sync its data to disk.
53 rm -rf $dir
54 mkdir $dir
55 keydesc=$(_generate_encryption_key)
56 $XFS_IO_PROG -c "set_encpolicy $keydesc" $dir
57 $XFS_IO_PROG -f $file -c "pwrite 0 $((nproc*slice))M" -c "fsync" > /dev/null
58
59 # Create processes to read from the encrypted file.  Use fadvise to wipe the
60 # pagecache before each read, ensuring that each read actually does decryption.
61 for ((proc = 0; proc < nproc; proc++)); do
62         (
63                 range="$((proc * slice))M ${slice}M"
64                 while [ ! -e $tmp.done ]; do
65                         $XFS_IO_PROG $file -c "fadvise -d $range" \
66                                            -c "pread $range" &> /dev/null
67                 done
68         ) &
69 done
70
71 # Wait a second for the readers to start up.
72 sleep 1
73
74 # Revoke the encryption key.
75 keyid=$(_revoke_encryption_key $keydesc)
76
77 # Now try to open the file again.  In buggy kernels this caused concurrent
78 # readers to crash with a NULL pointer dereference during decryption.
79 #
80 # Note that the fix also made filenames stop "immediately" reverting to their
81 # ciphertext on key revocation.  Therefore, the name of the file we're opening
82 # here may be in either plaintext or ciphertext depending on the kernel version,
83 # and ciphertext names are unpredictable anyway, so just use 'find' to find it.
84 cat "$(find $dir -type f)" > /dev/null
85
86 # Wait for readers to exit
87 touch $tmp.done
88 wait
89
90 # success, all done
91 echo "Didn't crash!"
92 status=0
93 exit