generic: test MADV_POPULATE_READ with IO errors
[xfstests-dev.git] / tests / generic / 397
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2016 Google, Inc.  All Rights Reserved.
4 #
5 # FS QA Test generic/397
6 #
7 # Test accessing encrypted files and directories, both with and without the
8 # encryption key.  Access with the encryption key is more of a sanity check and
9 # is not intended to fully test all the encrypted I/O paths; to do that you'd
10 # need to run all the xfstests with encryption enabled.  Access without the
11 # encryption key, on the other hand, should result in some particular behaviors.
12 #
13 . ./common/preamble
14 _begin_fstest auto quick encrypt
15
16 # Import common functions.
17 . ./common/filter
18 . ./common/encrypt
19
20 # real QA test starts here
21 _supported_fs generic
22 _require_symlinks
23 _require_scratch_encryption
24 _require_command "$KEYCTL_PROG" keyctl
25
26 _init_session_keyring
27
28 _scratch_mkfs_encrypted &>> $seqres.full
29 _scratch_mount
30
31 mkdir $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
32 keydesc=$(_generate_session_encryption_key)
33 _set_encpolicy $SCRATCH_MNT/edir $keydesc
34 for dir in $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir; do
35         touch $dir/empty > /dev/null
36         $XFS_IO_PROG -t -f -c "pwrite 0 4k" $dir/a > /dev/null
37         $XFS_IO_PROG -t -f -c "pwrite 0 33k" $dir/abcdefghijklmnopqrstuvwxyz > /dev/null
38         maxname=$(head -c 255 /dev/zero | tr '\0' y) # 255 character filename
39         $XFS_IO_PROG -t -f -c "pwrite 0 1k" $dir/$maxname > /dev/null
40         ln -s a $dir/symlink
41         ln -s abcdefghijklmnopqrstuvwxyz $dir/symlink2
42         ln -s $maxname $dir/symlink3
43         mkdir $dir/subdir
44         mkdir $dir/subdir/subsubdir
45 done
46 # Diff encrypted directory with unencrypted reference directory
47 diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
48 # Cycle mount and diff again
49 _scratch_cycle_mount
50 diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
51
52 #
53 # Now try accessing the files without the encryption key.  It should still be
54 # possible to list the directory and remove files.  But filenames should be
55 # presented in no-key form, and it should not be possible to read regular files
56 # or to create new files or subdirectories.
57 #
58 # Note that we cannot simply use ls -R to verify the files because the no-key
59 # filenames are unpredictable.  By design, the key used to encrypt a directory's
60 # filenames is derived from the master key (the key in the keyring) and a nonce
61 # generated by the kernel.  Hence, the no-key filenames will be different every
62 # time this test is run, even if we were to put a fixed key into the keyring
63 # instead of a random one.  The same applies to symlink targets.
64 #
65
66 _unlink_session_encryption_key $keydesc
67 _scratch_cycle_mount
68
69 # Check that unencrypted names aren't there
70 stat $SCRATCH_MNT/edir/empty |& _filter_stat |& _filter_scratch
71 stat $SCRATCH_MNT/edir/symlink |& _filter_stat |& _filter_scratch
72
73 # Check that the correct numbers of files and subdirectories are there
74 ls $SCRATCH_MNT/edir | wc -l
75 find $SCRATCH_MNT/edir -mindepth 2 -maxdepth 2 -type d | wc -l
76
77 # Try to read a nondirectory file (should fail with ENOKEY)
78 md5sum $(find $SCRATCH_MNT/edir -maxdepth 1 -type f | head -1) |& \
79                 cut -d ' ' -f3-
80
81 # Try to create new files, directories, and symlinks in the encrypted directory,
82 # both with and without using correctly base-64 encoded filenames.  These should
83 # all fail with ENOKEY.
84 $XFS_IO_PROG -f $SCRATCH_MNT/edir/newfile |& _filter_scratch
85 $XFS_IO_PROG -f $SCRATCH_MNT/edir/0123456789abcdef |& _filter_scratch
86 mkdir $SCRATCH_MNT/edir/newdir |& _filter_scratch
87 mkdir $SCRATCH_MNT/edir/0123456789abcdef |& _filter_scratch
88 ln -s foo $SCRATCH_MNT/edir/newlink |& _filter_scratch
89 ln -s foo $SCRATCH_MNT/edir/0123456789abcdef |& _filter_scratch
90
91 # Delete the encrypted directory (should succeed)
92 rm -r $SCRATCH_MNT/edir
93 stat $SCRATCH_MNT/edir |& _filter_stat |& _filter_scratch
94
95 # success, all done
96 status=0
97 exit