generic: ensure we drop suid after fallocate
[xfstests-dev.git] / tests / generic / 687
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2022 Oracle.  All Rights Reserved.
4 #
5 # FS QA Test No. 687
6 #
7 # Functional test for dropping suid and sgid bits as part of a fcollapse.
8 #
9 . ./common/preamble
10 _begin_fstest auto clone quick
11
12 # Override the default cleanup function.
13 _cleanup()
14 {
15         cd /
16         rm -r -f $tmp.* $junk_dir
17 }
18
19 # Import common functions.
20 . ./common/filter
21 . ./common/reflink
22
23 # real QA test starts here
24
25 # Modify as appropriate.
26 _supported_fs generic
27 _require_user
28 _require_test
29 verb=fcollapse
30 _require_xfs_io_command $verb
31
32 junk_dir=$TEST_DIR/$seq
33 junk_file=$junk_dir/a
34 mkdir -p $junk_dir/
35 chmod a+rw $junk_dir/
36
37 setup_testfile() {
38         rm -f $junk_file
39         _pwrite_byte 0x58 0 192k $junk_file >> $seqres.full
40         sync
41 }
42
43 commit_and_check() {
44         local user="$1"
45         local command="$2"
46         local start="$3"
47         local end="$4"
48
49         stat -c '%a %A %n' $junk_file | _filter_test_dir
50
51         local cmd="$XFS_IO_PROG -c '$command $start $end' $junk_file"
52         if [ -n "$user" ]; then
53                 su - "$user" -c "$cmd" >> $seqres.full
54         else
55                 $SHELL -c "$cmd" >> $seqres.full
56         fi
57
58         stat -c '%a %A %n' $junk_file | _filter_test_dir
59
60         # Blank line in output
61         echo
62 }
63
64 nr=0
65 # Commit to a non-exec file by an unprivileged user clears suid but
66 # leaves sgid.
67 nr=$((nr + 1))
68 echo "Test $nr - qa_user, non-exec file $verb"
69 setup_testfile
70 chmod a+rws $junk_file
71 commit_and_check "$qa_user" "$verb" 64k 64k
72
73 # Commit to a group-exec file by an unprivileged user clears suid and
74 # sgid.
75 nr=$((nr + 1))
76 echo "Test $nr - qa_user, group-exec file $verb"
77 setup_testfile
78 chmod g+x,a+rws $junk_file
79 commit_and_check "$qa_user" "$verb" 64k 64k
80
81 # Commit to a user-exec file by an unprivileged user clears suid but
82 # not sgid.
83 nr=$((nr + 1))
84 echo "Test $nr - qa_user, user-exec file $verb"
85 setup_testfile
86 chmod u+x,a+rws,g-x $junk_file
87 commit_and_check "$qa_user" "$verb" 64k 64k
88
89 # Commit to a all-exec file by an unprivileged user clears suid and
90 # sgid.
91 nr=$((nr + 1))
92 echo "Test $nr - qa_user, all-exec file $verb"
93 setup_testfile
94 chmod a+rwxs $junk_file
95 commit_and_check "$qa_user" "$verb" 64k 64k
96
97 # Commit to a non-exec file by root clears suid but leaves sgid.
98 nr=$((nr + 1))
99 echo "Test $nr - root, non-exec file $verb"
100 setup_testfile
101 chmod a+rws $junk_file
102 commit_and_check "" "$verb" 64k 64k
103
104 # Commit to a group-exec file by root clears suid and sgid.
105 nr=$((nr + 1))
106 echo "Test $nr - root, group-exec file $verb"
107 setup_testfile
108 chmod g+x,a+rws $junk_file
109 commit_and_check "" "$verb" 64k 64k
110
111 # Commit to a user-exec file by root clears suid but not sgid.
112 nr=$((nr + 1))
113 echo "Test $nr - root, user-exec file $verb"
114 setup_testfile
115 chmod u+x,a+rws,g-x $junk_file
116 commit_and_check "" "$verb" 64k 64k
117
118 # Commit to a all-exec file by root clears suid and sgid.
119 nr=$((nr + 1))
120 echo "Test $nr - root, all-exec file $verb"
121 setup_testfile
122 chmod a+rwxs $junk_file
123 commit_and_check "" "$verb" 64k 64k
124
125 # success, all done
126 status=0
127 exit