]> git.apps.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
generic: test suid/sgid behavior with reflink and dedupe
authorDarrick J. Wong <djwong@kernel.org>
Thu, 27 Jan 2022 01:27:01 +0000 (17:27 -0800)
committerEryu Guan <guaneryu@gmail.com>
Sun, 13 Feb 2022 16:53:30 +0000 (00:53 +0800)
Make sure that we drop the setuid and setgid bits any time reflink or
dedupe change the file contents.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
tests/generic/673 [new file with mode: 0755]
tests/generic/673.out [new file with mode: 0644]
tests/generic/674 [new file with mode: 0755]
tests/generic/674.out [new file with mode: 0644]
tests/generic/675 [new file with mode: 0755]
tests/generic/675.out [new file with mode: 0644]

diff --git a/tests/generic/673 b/tests/generic/673
new file mode 100755 (executable)
index 0000000..0377c5f
--- /dev/null
@@ -0,0 +1,107 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 673
+#
+# Functional test for dropping suid and sgid bits as part of a reflink.
+#
+. ./common/preamble
+_begin_fstest auto clone quick
+
+# Import common functions.
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_require_user
+_require_scratch_reflink
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+chmod a+rw $SCRATCH_MNT/
+
+setup_testfile() {
+       rm -f $SCRATCH_MNT/a $SCRATCH_MNT/b
+       _pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+       _pwrite_byte 0x57 0 1m $SCRATCH_MNT/b >> $seqres.full
+       chmod a+r $SCRATCH_MNT/b
+       sync
+}
+
+commit_and_check() {
+       local user="$1"
+
+       md5sum $SCRATCH_MNT/a | _filter_scratch
+       stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch
+
+       local cmd="$XFS_IO_PROG -c 'reflink $SCRATCH_MNT/b 0 0 1m' $SCRATCH_MNT/a"
+       if [ -n "$user" ]; then
+               su - "$user" -c "$cmd" >> $seqres.full
+       else
+               $SHELL -c "$cmd" >> $seqres.full
+       fi
+
+       _scratch_cycle_mount
+       md5sum $SCRATCH_MNT/a | _filter_scratch
+       stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch
+
+       # Blank line in output
+       echo
+}
+
+# Commit to a non-exec file by an unprivileged user clears suid but leaves
+# sgid.
+echo "Test 1 - qa_user, non-exec file"
+setup_testfile
+chmod a+rws $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a group-exec file by an unprivileged user clears suid and sgid.
+echo "Test 2 - qa_user, group-exec file"
+setup_testfile
+chmod g+x,a+rws $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a user-exec file by an unprivileged user clears suid but not sgid.
+echo "Test 3 - qa_user, user-exec file"
+setup_testfile
+chmod u+x,a+rws,g-x $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a all-exec file by an unprivileged user clears suid and sgid.
+echo "Test 4 - qa_user, all-exec file"
+setup_testfile
+chmod a+rwxs $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a non-exec file by root clears suid but leaves sgid.
+echo "Test 5 - root, non-exec file"
+setup_testfile
+chmod a+rws $SCRATCH_MNT/a
+commit_and_check
+
+# Commit to a group-exec file by root clears suid and sgid.
+echo "Test 6 - root, group-exec file"
+setup_testfile
+chmod g+x,a+rws $SCRATCH_MNT/a
+commit_and_check
+
+# Commit to a user-exec file by root clears suid but not sgid.
+echo "Test 7 - root, user-exec file"
+setup_testfile
+chmod u+x,a+rws,g-x $SCRATCH_MNT/a
+commit_and_check
+
+# Commit to a all-exec file by root clears suid and sgid.
+echo "Test 8 - root, all-exec file"
+setup_testfile
+chmod a+rwxs $SCRATCH_MNT/a
+commit_and_check
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/673.out b/tests/generic/673.out
new file mode 100644 (file)
index 0000000..8df672d
--- /dev/null
@@ -0,0 +1,49 @@
+QA output created by 673
+Test 1 - qa_user, non-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+2666 -rw-rwSrw- SCRATCH_MNT/a
+
+Test 2 - qa_user, group-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+676 -rw-rwxrw- SCRATCH_MNT/a
+
+Test 3 - qa_user, user-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+2766 -rwxrwSrw- SCRATCH_MNT/a
+
+Test 4 - qa_user, all-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+777 -rwxrwxrwx SCRATCH_MNT/a
+
+Test 5 - root, non-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+
+Test 6 - root, group-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+
+Test 7 - root, user-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+
+Test 8 - root, all-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+3784de23efab7a2074c9ec66901e39e5  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+
diff --git a/tests/generic/674 b/tests/generic/674
new file mode 100755 (executable)
index 0000000..bf0bcff
--- /dev/null
@@ -0,0 +1,117 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 674
+#
+# Functional test for dropping suid and sgid bits as part of a deduplication.
+#
+. ./common/preamble
+_begin_fstest auto clone quick
+
+# Import common functions.
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_require_user
+_require_scratch_reflink
+_require_xfs_io_command dedupe
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+chmod a+rw $SCRATCH_MNT/
+
+setup_testfile() {
+       rm -f $SCRATCH_MNT/a $SCRATCH_MNT/b
+       _pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+       _pwrite_byte 0x58 0 1m $SCRATCH_MNT/b >> $seqres.full
+       chmod a+r $SCRATCH_MNT/b
+       sync
+}
+
+commit_and_check() {
+       local user="$1"
+
+       md5sum $SCRATCH_MNT/a | _filter_scratch
+       stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch
+
+       local before_freesp=$(_get_available_space $SCRATCH_MNT)
+
+       local cmd="$XFS_IO_PROG -c 'dedupe $SCRATCH_MNT/b 0 0 1m' $SCRATCH_MNT/a"
+       if [ -n "$user" ]; then
+               su - "$user" -c "$cmd" >> $seqres.full
+       else
+               $SHELL -c "$cmd" >> $seqres.full
+       fi
+
+       _scratch_cycle_mount
+       md5sum $SCRATCH_MNT/a | _filter_scratch
+       stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch
+
+       local after_freesp=$(_get_available_space $SCRATCH_MNT)
+
+       echo "before: $before_freesp; after: $after_freesp" >> $seqres.full
+       if [ $after_freesp -le $before_freesp ]; then
+               echo "expected more free space after dedupe"
+       fi
+
+       # Blank line in output
+       echo
+}
+
+# Commit to a non-exec file by an unprivileged user clears suid but leaves
+# sgid.
+echo "Test 1 - qa_user, non-exec file"
+setup_testfile
+chmod a+rws $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a group-exec file by an unprivileged user clears suid and sgid.
+echo "Test 2 - qa_user, group-exec file"
+setup_testfile
+chmod g+x,a+rws $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a user-exec file by an unprivileged user clears suid but not sgid.
+echo "Test 3 - qa_user, user-exec file"
+setup_testfile
+chmod u+x,a+rws,g-x $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a all-exec file by an unprivileged user clears suid and sgid.
+echo "Test 4 - qa_user, all-exec file"
+setup_testfile
+chmod a+rwxs $SCRATCH_MNT/a
+commit_and_check "$qa_user"
+
+# Commit to a non-exec file by root clears suid but leaves sgid.
+echo "Test 5 - root, non-exec file"
+setup_testfile
+chmod a+rws $SCRATCH_MNT/a
+commit_and_check
+
+# Commit to a group-exec file by root clears suid and sgid.
+echo "Test 6 - root, group-exec file"
+setup_testfile
+chmod g+x,a+rws $SCRATCH_MNT/a
+commit_and_check
+
+# Commit to a user-exec file by root clears suid but not sgid.
+echo "Test 7 - root, user-exec file"
+setup_testfile
+chmod u+x,a+rws,g-x $SCRATCH_MNT/a
+commit_and_check
+
+# Commit to a all-exec file by root clears suid and sgid.
+echo "Test 8 - root, all-exec file"
+setup_testfile
+chmod a+rwxs $SCRATCH_MNT/a
+commit_and_check
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/674.out b/tests/generic/674.out
new file mode 100644 (file)
index 0000000..a2660c7
--- /dev/null
@@ -0,0 +1,49 @@
+QA output created by 674
+Test 1 - qa_user, non-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+
+Test 2 - qa_user, group-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+
+Test 3 - qa_user, user-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+
+Test 4 - qa_user, all-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+
+Test 5 - root, non-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6666 -rwSrwSrw- SCRATCH_MNT/a
+
+Test 6 - root, group-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6676 -rwSrwsrw- SCRATCH_MNT/a
+
+Test 7 - root, user-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6766 -rwsrwSrw- SCRATCH_MNT/a
+
+Test 8 - root, all-exec file
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/a
+6777 -rwsrwsrwx SCRATCH_MNT/a
+
diff --git a/tests/generic/675 b/tests/generic/675
new file mode 100755 (executable)
index 0000000..23b7e54
--- /dev/null
@@ -0,0 +1,70 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test No. 675
+#
+# Functional test for dropping suid and sgid capabilities as part of a reflink.
+#
+. ./common/preamble
+_begin_fstest auto clone quick
+
+# Import common functions.
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_require_user
+_require_command "$GETCAP_PROG" getcap
+_require_command "$SETCAP_PROG" setcap
+_require_scratch_reflink
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+chmod a+rw $SCRATCH_MNT/
+
+setup_testfile() {
+       rm -f $SCRATCH_MNT/a $SCRATCH_MNT/b
+       _pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+       _pwrite_byte 0x57 0 1m $SCRATCH_MNT/b >> $seqres.full
+       chmod a+rwx $SCRATCH_MNT/a $SCRATCH_MNT/b
+       $SETCAP_PROG cap_setgid,cap_setuid+ep $SCRATCH_MNT/a
+       sync
+}
+
+commit_and_check() {
+       local user="$1"
+
+       stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch
+       _getcap -v $SCRATCH_MNT/a | _filter_scratch
+
+       local cmd="$XFS_IO_PROG -c 'reflink $SCRATCH_MNT/b 0 0 1m' $SCRATCH_MNT/a"
+       if [ -n "$user" ]; then
+               su - "$user" -c "$cmd" >> $seqres.full
+       else
+               $SHELL -c "$cmd" >> $seqres.full
+       fi
+
+       stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch
+       _getcap -v $SCRATCH_MNT/a | _filter_scratch
+
+       # Blank line in output
+       echo
+}
+
+# Commit by an unprivileged user clears capability bits.
+echo "Test 1 - qa_user"
+setup_testfile
+commit_and_check "$qa_user"
+
+# Commit by root leaves capability bits.
+echo "Test 2 - root"
+setup_testfile
+commit_and_check
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/675.out b/tests/generic/675.out
new file mode 100644 (file)
index 0000000..626eb60
--- /dev/null
@@ -0,0 +1,13 @@
+QA output created by 675
+Test 1 - qa_user
+777 -rwxrwxrwx SCRATCH_MNT/a
+SCRATCH_MNT/a cap_setgid,cap_setuid=ep
+777 -rwxrwxrwx SCRATCH_MNT/a
+SCRATCH_MNT/a
+
+Test 2 - root
+777 -rwxrwxrwx SCRATCH_MNT/a
+SCRATCH_MNT/a cap_setgid,cap_setuid=ep
+777 -rwxrwxrwx SCRATCH_MNT/a
+SCRATCH_MNT/a
+