generic/398: accept EXDEV for rename or link into encrypted dir
[xfstests-dev.git] / tests / generic / 398
index efb8348c92746d85ee838ecc7b368daab5ac48c1..ecf826901689ccf5c22af86eb8667b7b36ed675e 100755 (executable)
@@ -7,9 +7,9 @@
 # Filesystem encryption is designed to enforce that a consistent encryption
 # policy is used within a given encrypted directory tree and that an encrypted
 # directory tree does not contain any unencrypted files.  This test verifies
-# that filesystem operations that would violate this constraint fail with EPERM.
-# This does not test enforcement of this constraint on lookup, which is still
-# needed to detect offline changes.
+# that filesystem operations that would violate this constraint fail.  This does
+# not test enforcement of this constraint on lookup, which is still needed to
+# detect offline changes.
 #
 seq=`basename $0`
 seqres=$RESULT_DIR/$seq
@@ -26,10 +26,21 @@ _cleanup()
        rm -f $tmp.*
 }
 
-filter_enokey()
+# The error code for incompatible rename or link into an encrypted directory was
+# changed from EPERM to EXDEV in Linux v5.1, to allow tools like 'mv' to work.
+# See kernel commit f5e55e777cc9 ("fscrypt: return -EXDEV for incompatible
+# rename or link into encrypted dir").  Accept both errors for now.
+filter_eperm_to_exdev()
 {
-       # rename without key can also fail with EPERM instead of ENOKEY
-       sed -e "s/Required key not available/Operation not permitted/g"
+       sed -e 's/Operation not permitted/Invalid cross-device link/'
+}
+
+# The error code for incompatible cross-rename without the key has been ENOKEY
+# on all filesystems since Linux v4.16.  Previously it was EPERM on some
+# filesystems.  Accept both errors for now.
+filter_eperm_to_enokey()
+{
+       sed -e 's/Operation not permitted/Required key not available/'
 }
 
 # get standard environment, filters and checks
@@ -67,27 +78,27 @@ touch $edir2/efile2
 touch $udir/ufile
 
 
-# Test linking and moving an encrypted file into an encrypted directory with a
-# different encryption policy.  Should fail with EPERM.
+# Test linking and renaming an encrypted file into an encrypted directory with a
+# different encryption policy.  Should fail with EXDEV.
 
 echo -e "\n*** Link encrypted <= encrypted ***"
-ln $edir1/efile1 $edir2/efile1 |& _filter_scratch
+ln $edir1/efile1 $edir2/efile1 |& _filter_scratch | filter_eperm_to_exdev
 
 echo -e "\n*** Rename encrypted => encrypted ***"
-mv $edir1/efile1 $edir2/efile1 |& _filter_scratch
+src/renameat2 $edir1/efile1 $edir2/efile1 |& filter_eperm_to_exdev
 
 
-# Test linking and moving an unencrypted file into an encrypted directory.
-# Should fail with EPERM.
+# Test linking and renaming an unencrypted file into an encrypted directory.
+# Should fail with EXDEV.
 
 echo -e "\n\n*** Link unencrypted <= encrypted ***"
-ln $udir/ufile $edir1/ufile |& _filter_scratch
+ln $udir/ufile $edir1/ufile |& _filter_scratch | filter_eperm_to_exdev
 
 echo -e "\n*** Rename unencrypted => encrypted ***"
-mv $udir/ufile $edir1/ufile |& _filter_scratch
+src/renameat2 $udir/ufile $edir1/ufile |& filter_eperm_to_exdev
 
 
-# Test linking and moving an encrypted file into an unencrypted directory.
+# Test linking and renaming an encrypted file into an unencrypted directory.
 # Should succeed.
 
 echo -e "\n\n*** Link encrypted <= unencrypted ***"
@@ -95,33 +106,33 @@ ln -v $edir1/efile1 $udir/efile1 |& _filter_scratch
 rm $udir/efile1 # undo
 
 echo -e "\n*** Rename encrypted => unencrypted ***"
-mv -v $edir1/efile1 $udir/efile1 |& _filter_scratch |& _filter_mv
-mv $udir/efile1 $edir1/efile1 # undo
+src/renameat2 $edir1/efile1 $udir/efile1
+src/renameat2 $udir/efile1 $edir1/efile1 # undo
 
 
-# Test moving a forbidden (unencrypted, or encrypted with a different encryption
-# policy) file into an encrypted directory via an exchange (cross rename)
-# operation.  Should fail with EPERM.
+# Test renaming a forbidden (unencrypted, or encrypted with a different
+# encryption policy) file into an encrypted directory via an exchange (cross
+# rename) operation.  Should fail with EXDEV.
 
 echo -e "\n\n*** Exchange encrypted <=> encrypted ***"
-src/renameat2 -x $edir1/efile1 $edir2/efile2 |& _filter_scratch
+src/renameat2 -x $edir1/efile1 $edir2/efile2 |& filter_eperm_to_exdev
 
 echo -e "\n*** Exchange unencrypted <=> encrypted ***"
-src/renameat2 -x $udir/ufile $edir1/efile1 |& _filter_scratch
+src/renameat2 -x $udir/ufile $edir1/efile1 |& filter_eperm_to_exdev
 
 echo -e "\n*** Exchange encrypted <=> unencrypted ***"
-src/renameat2 -x $edir1/efile1 $udir/ufile |& _filter_scratch
+src/renameat2 -x $edir1/efile1 $udir/ufile |& filter_eperm_to_exdev
 
 
 # Test a file with a special type, i.e. not regular, directory, or symlink.
 # Since such files are not subject to encryption, there should be no
-# restrictions on linking or moving them into encrypted directories.
+# restrictions on linking or renaming them into encrypted directories.
 
 echo -e "\n\n*** Special file tests ***"
 mkfifo $edir1/fifo
-mv -v $edir1/fifo $edir2/fifo | _filter_scratch |& _filter_mv
-mv -v $edir2/fifo $udir/fifo | _filter_scratch |& _filter_mv
-mv -v $udir/fifo $edir1/fifo | _filter_scratch |& _filter_mv
+src/renameat2 $edir1/fifo $edir2/fifo
+src/renameat2 $edir2/fifo $udir/fifo
+src/renameat2 $udir/fifo $edir1/fifo
 mkfifo $udir/fifo
 src/renameat2 -x $udir/fifo $edir1/fifo
 ln -v $edir1/fifo $edir2/fifo | _filter_scratch
@@ -138,9 +149,9 @@ efile1=$(find $edir1 -type f)
 efile2=$(find $edir2 -type f)
 
 echo -e "\n\n*** Exchange encrypted <=> encrypted without key ***"
-src/renameat2 -x $efile1 $efile2 |& filter_enokey
+src/renameat2 -x $efile1 $efile2 |& filter_eperm_to_enokey
 echo -e "\n*** Exchange encrypted <=> unencrypted without key ***"
-src/renameat2 -x $efile1 $udir/ufile |& filter_enokey
+src/renameat2 -x $efile1 $udir/ufile |& filter_eperm_to_enokey
 
 # success, all done
 status=0