1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
##/bin/bash
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
#
# common extended attribute and ACL support
# filesystems that want to test maximum supported acl counts need to
# add support in here
_acl_get_max()
{
case $FSTYP in
xfs)
# CRC format filesystems have much larger ACL counts. The actual
# number is into the thousands, but testing that meany takes too
# long, so just test well past the old limit of 25.
$XFS_INFO_PROG $TEST_DIR | _filter_mkfs > /dev/null 2> $tmp.info
. $tmp.info
rm $tmp.info
if [ $_fs_has_crcs -eq 0 ]; then
echo 25
else
echo 5461
fi
;;
jfs)
echo 8191
;;
f2fs)
# If noinline_xattr is enabled, max xattr size should be:
# (4096 - 24) - (24 + 4) = 4044
# then ACL_MAX_ENTRIES should be:
# (4044 - (4 + 4 * 4)) / 8 + 4 = 507
_fs_options $TEST_DEV | grep "noinline_xattr" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo 507
else
# If inline_xattr is enabled, max xattr size should be:
# (4096 - 24 + 200) - (24 + 4) = 4244
# then ACL_MAX_ENTRIES should be:
# (4244 - (4 + 4 * 4)) / 8 + 4 = 532
_fs_options $TEST_DEV | grep "inline_xattr" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo 532
else
echo 507
fi
fi
;;
bcachefs)
echo 251
;;
*)
echo 0
;;
esac
}
_require_acl_get_max()
{
if [ $(_acl_get_max) -eq 0 ]; then
_notrun "$FSTYP does not define maximum ACL count"
fi
}
# pick three unused user/group ids, store them as $acl[1-3]
#
_acl_setup_ids()
{
eval `(_cat_passwd; _cat_group) | awk -F: '
{ ids[$3]=1 }
END {
j=1
for(i=1; i<1000000 && j<=3;i++){
if (! (i in ids)) {
printf "acl%d=%d;", j, i;
j++
}
}
}'`
}
# filter for the acl ids selected above
#
_acl_filter_id()
{
sed \
-e "s/u:$acl1/u:id1/" \
-e "s/u:$acl2/u:id2/" \
-e "s/u:$acl3/u:id3/" \
-e "s/g:$acl1/g:id1/" \
-e "s/g:$acl2/g:id2/" \
-e "s/g:$acl3/g:id3/" \
-e "s/ $acl1 / id1 /" \
-e "s/ $acl2 / id2 /" \
-e "s/ $acl3 / id3 /"
}
_getfacl_filter_id()
{
sed \
-e "s/user:$acl1/user:id1/" \
-e "s/user:$acl2/user:id2/" \
-e "s/user:$acl3/user:id3/" \
-e "s/group:$acl1/group:id1/" \
-e "s/group:$acl2/group:id2/" \
-e "s/group:$acl3/group:id3/" \
-e "s/: $acl1/: id1/" \
-e "s/: $acl2/: id2/" \
-e "s/: $acl3/: id3/"
}
# filtered ls
#
_acl_ls()
{
_ls_l -n $* | awk '{ print $1, $3, $4, $NF }' | _acl_filter_id
}
# create an ACL with n ACEs in it
#
_create_n_aces()
{
let n=$1-4
acl='u::rwx,g::rwx,o::rwx,m::rwx' # 4 ace acl start
while [ $n -ne 0 ]; do
acl="$acl,u:$n:rwx"
let n=$n-1
done
echo $acl
}
# filter user ace names to user ids
#
_filter_aces()
{
tmp_file=`mktemp /tmp/ace.XXXXXX`
(_cat_passwd; _cat_group) > $tmp_file
$AWK_PROG -v tmpfile=$tmp_file '
BEGIN {
FS=":"
while ( getline <tmpfile > 0 ) {
idlist[$1] = $3
}
}
/^user/ { if ($2 in idlist) sub($2, idlist[$2]); print; next}
/^u/ { if ($2 in idlist) sub($2, idlist[$2]); print; next}
/^default:user/ { if ($3 in idlist) sub($3, idlist[$3]); print; next}
{print}
'
rm -f $tmp_file
}
_filter_aces_notypes()
{
tr '\[' '\012' | tr ']' '\012' | tr ',' '\012' | _filter_aces|\
sed -e 's/u:/user:/' -e 's/g:/group:/' -e 's/o:/other:/' -e 's/m:/mask:/'
}
_require_acls()
{
[ -n "$CHACL_PROG" ] || _notrun "chacl command not found"
#
# Test if chacl is able to set an ACL on a file. On really old kernels
# the system calls might not be implemented at all, but the more common
# case is that the tested filesystem simply doesn't support ACLs.
#
touch $TEST_DIR/syscalltest
chacl 'u::rw-,g::---,o::---' $TEST_DIR/syscalltest > $TEST_DIR/syscalltest.out 2>&1
cat $TEST_DIR/syscalltest.out >> $seqres.full
if grep -q 'Function not implemented' $TEST_DIR/syscalltest.out; then
_notrun "kernel does not support ACLs"
fi
if grep -q 'Operation not supported' $TEST_DIR/syscalltest.out; then
_notrun "ACLs not supported by this filesystem type: $FSTYP"
fi
rm -f $TEST_DIR/syscalltest.out
}
_list_acl()
{
file=$1
ls -dD $file | _acl_filter_id
}
_require_attrs()
{
local args
local nsp
if [ $# -eq 0 ]; then
args="user"
else
args="$*"
fi
[ -n "$ATTR_PROG" ] || _notrun "attr command not found"
[ -n "$GETFATTR_PROG" ] || _notrun "getfattr command not found"
[ -n "$SETFATTR_PROG" ] || _notrun "setfattr command not found"
for nsp in $args; do
#
# Test if chacl is able to write an attribute on the target
# filesystems. On really old kernels the system calls might
# not be implemented at all, but the more common case is that
# the tested filesystem simply doesn't support attributes.
# Note that we can't simply list attributes as various security
# modules generate synthetic attributes not actually stored on
# disk.
#
touch $TEST_DIR/syscalltest
$SETFATTR_PROG -n "$nsp.xfstests" -v "attr" $TEST_DIR/syscalltest > $TEST_DIR/syscalltest.out 2>&1
cat $TEST_DIR/syscalltest.out >> $seqres.full
if grep -q 'Function not implemented' $TEST_DIR/syscalltest.out; then
_notrun "kernel does not support attrs"
fi
if grep -q 'Operation not supported' $TEST_DIR/syscalltest.out; then
_notrun "attr namespace $nsp not supported by this filesystem type: $FSTYP"
fi
rm -f $TEST_DIR/syscalltest.out
done
}
_require_attr_v1()
{
_scratch_mkfs_xfs_supported -i attr=1 >/dev/null 2>&1 \
|| _notrun "attr v1 not supported on $SCRATCH_DEV"
}
# check if we support the noattr2 mount option
_require_noattr2()
{
_scratch_mkfs_xfs > /dev/null 2>&1 \
|| _fail "_scratch_mkfs_xfs failed on $SCRATCH_DEV"
_try_scratch_mount -o noattr2 > /dev/null 2>&1 \
|| _notrun "noattr2 mount option not supported on $SCRATCH_DEV"
_scratch_unmount
}
# getfattr -R returns info in readdir order which varies from fs to fs.
# This sorts the output by filename
_sort_getfattr_output()
{
awk '{a[FNR]=$0}END{n = asort(a); for(i=1; i <= n; i++) print a[i]"\n"}' RS=''
}
# Previously, when getfattr dumps values of all extended attributes, it prints
# empty attr as 'user.name', but new getfattr (since attr-2.4.48) prints it as
# 'user.name=""'. Filter out the ending '=""' so that both old and new getfattr
# pints the same output.
#
# Note: This function returns the getfattr command result.
_getfattr()
{
$GETFATTR_PROG "$@" | sed -e 's/=\"\"//'
return ${PIPESTATUS[0]}
}
# make sure this script returns success
/bin/true
|