| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2016 Google, Inc. All Rights Reserved. |
| # |
| # FS QA Test generic/397 |
| # |
| # Test accessing encrypted files and directories, both with and without the |
| # encryption key. Access with the encryption key is more of a sanity check and |
| # is not intended to fully test all the encrypted I/O paths; to do that you'd |
| # need to run all the xfstests with encryption enabled. Access without the |
| # encryption key, on the other hand, should result in some particular behaviors. |
| # |
| seq=`basename $0` |
| seqres=$RESULT_DIR/$seq |
| echo "QA output created by $seq" |
| |
| here=`pwd` |
| tmp=/tmp/$$ |
| status=1 # failure is the default! |
| trap "_cleanup; exit \$status" 0 1 2 3 15 |
| |
| _cleanup() |
| { |
| cd / |
| rm -f $tmp.* |
| } |
| |
| # get standard environment, filters and checks |
| . ./common/rc |
| . ./common/filter |
| . ./common/encrypt |
| |
| # remove previous $seqres.full before test |
| rm -f $seqres.full |
| |
| # real QA test starts here |
| _supported_fs generic |
| _require_symlinks |
| _require_scratch_encryption |
| _require_command "$KEYCTL_PROG" keyctl |
| |
| _new_session_keyring |
| |
| _scratch_mkfs_encrypted &>> $seqres.full |
| _scratch_mount |
| |
| mkdir $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir |
| keydesc=$(_generate_session_encryption_key) |
| _set_encpolicy $SCRATCH_MNT/edir $keydesc |
| for dir in $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir; do |
| touch $dir/empty > /dev/null |
| $XFS_IO_PROG -t -f -c "pwrite 0 4k" $dir/a > /dev/null |
| $XFS_IO_PROG -t -f -c "pwrite 0 33k" $dir/abcdefghijklmnopqrstuvwxyz > /dev/null |
| maxname=$(head -c 255 /dev/zero | tr '\0' y) # 255 character filename |
| $XFS_IO_PROG -t -f -c "pwrite 0 1k" $dir/$maxname > /dev/null |
| ln -s a $dir/symlink |
| ln -s abcdefghijklmnopqrstuvwxyz $dir/symlink2 |
| ln -s $maxname $dir/symlink3 |
| mkdir $dir/subdir |
| mkdir $dir/subdir/subsubdir |
| done |
| # Diff encrypted directory with unencrypted reference directory |
| diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir |
| # Cycle mount and diff again |
| _scratch_cycle_mount |
| diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir |
| |
| # |
| # Now try accessing the files without the encryption key. It should still be |
| # possible to list the directory and remove files. But filenames should be |
| # encrypted, and it should not be possible to read regular files or to create |
| # new files or subdirectories. |
| # |
| # Note that we cannot simply use ls -R to verify the files because the encrypted |
| # filenames are unpredictable. By design, the key used to encrypt a directory's |
| # filenames is derived from the master key (the key in the keyring) and a nonce |
| # generated by the kernel. Hence, the encrypted filenames will be different |
| # every time this test is run, even if we were to put a fixed key into the |
| # keyring instead of a random one. The same applies to symlink targets. |
| # |
| |
| _unlink_session_encryption_key $keydesc |
| _scratch_cycle_mount |
| |
| # Check that unencrypted names aren't there |
| stat $SCRATCH_MNT/edir/empty |& _filter_stat |& _filter_scratch |
| stat $SCRATCH_MNT/edir/symlink |& _filter_stat |& _filter_scratch |
| |
| # Check that the correct numbers of files and subdirectories are there |
| ls $SCRATCH_MNT/edir | wc -l |
| find $SCRATCH_MNT/edir -mindepth 2 -maxdepth 2 -type d | wc -l |
| |
| # Try to read a nondirectory file (should fail with ENOKEY) |
| md5sum $(find $SCRATCH_MNT/edir -maxdepth 1 -type f | head -1) |& \ |
| cut -d ' ' -f3- |
| |
| # Try to create new files, directories, and symlinks in the encrypted directory, |
| # both with and without using correctly base-64 encoded filenames. These should |
| # all fail with ENOKEY. |
| $XFS_IO_PROG -f $SCRATCH_MNT/edir/newfile |& _filter_scratch |
| $XFS_IO_PROG -f $SCRATCH_MNT/edir/0123456789abcdef |& _filter_scratch |
| mkdir $SCRATCH_MNT/edir/newdir |& _filter_scratch |
| mkdir $SCRATCH_MNT/edir/0123456789abcdef |& _filter_scratch |
| ln -s foo $SCRATCH_MNT/edir/newlink |& _filter_scratch |
| ln -s foo $SCRATCH_MNT/edir/0123456789abcdef |& _filter_scratch |
| |
| # Delete the encrypted directory (should succeed) |
| rm -r $SCRATCH_MNT/edir |
| stat $SCRATCH_MNT/edir |& _filter_stat |& _filter_scratch |
| |
| # success, all done |
| status=0 |
| exit |