xref: /freebsd/tests/sys/mac/bsdextended/matches_test.sh (revision 6f63e88c0166ed3e5f2805a9e667c7d24d304cf1)
1#!/bin/sh
2#
3# $FreeBSD$
4#
5
6uidrange="60000:100000"
7gidrange="60000:100000"
8uidinrange="nobody"
9uidoutrange="daemon"
10gidinrange="nobody" # We expect $uidinrange in this group
11gidoutrange="daemon" # We expect $uidinrange in this group
12
13
14check_ko()
15{
16	if ! sysctl -N security.mac.bsdextended >/dev/null 2>&1; then
17		atf_skip "mac_bsdextended(4) support isn't available"
18	fi
19}
20
21setup()
22{
23	check_ko
24	mkdir mnt
25	mdmfs -s 25m md mnt \
26		|| atf_fail "failed to mount md device"
27	chmod a+rwx mnt
28	md_device=$(mount -p | grep "$PWD/mnt" | awk '{ gsub(/^\/dev\//, "", $1); print $1 }')
29	if [ -z "$md_device" ]; then
30		atf_fail "md device not properly attached to the system"
31	fi
32	echo $md_device > md_device
33
34	ugidfw remove 1
35
36	cat > mnt/test-script.sh <<'EOF'
37#!/bin/sh
38: > $1
39EOF
40	if [ $? -ne 0 ]; then
41		atf_fail "failed to create test script"
42	fi
43
44	file1=mnt/test-$uidinrange
45	file2=mnt/test-$uidoutrange
46	command1="sh mnt/test-script.sh $file1"
47	command2="sh mnt/test-script.sh $file2"
48
49	# $uidinrange file
50	atf_check -s exit:0 su -m $uidinrange -c "$command1"
51
52	chown "$uidinrange":"$gidinrange" $file1
53	chmod a+w $file1
54
55	# $uidoutrange file
56	if ! $command2; then
57		atf_fail $desc
58	fi
59
60	chown "$uidoutrange":"$gidoutrange" $file2
61	chmod a+w $file2
62}
63
64cleanup()
65{
66	ugidfw remove 1
67
68	umount -f mnt
69	if [ -f md_device ]; then
70		mdconfig -d -u $( cat md_device )
71	fi
72}
73
74atf_test_case no_rules cleanup
75no_rules_head()
76{
77	atf_set "require.user" "root"
78}
79no_rules_body()
80{
81	setup
82
83	# no rules $uidinrange
84	atf_check -s exit:0 su -fm $uidinrange -c "$command1"
85
86	# no rules $uidoutrange
87	atf_check -s exit:0 su -fm $uidoutrange -c "$command1"
88}
89no_rules_cleanup()
90{
91	cleanup
92}
93
94atf_test_case subject_match_on_uid cleanup
95subject_match_on_uid_head()
96{
97	atf_set "require.user" "root"
98}
99subject_match_on_uid_body()
100{
101	setup
102
103	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object mode rasx
104	# subject uid in range
105	atf_check -s not-exit:0 -e match:"Permission denied" \
106		su -fm $uidinrange -c "$command1"
107
108	# subject uid out range
109	atf_check -s exit:0 su -fm $uidoutrange -c "$command1"
110
111}
112subject_match_on_uid_cleanup()
113{
114	cleanup
115}
116
117atf_test_case subject_match_on_gid cleanup
118subject_match_on_gid_head()
119{
120	atf_set "require.user" "root"
121}
122subject_match_on_gid_body()
123{
124	setup
125
126	atf_check -s exit:0 ugidfw set 1 subject gid $gidrange object mode rasx
127
128	# subject gid in range
129	atf_check -s not-exit:0 -e match:"Permission denied" \
130		su -fm $uidinrange -c "$command1"
131
132	# subject gid out range
133	atf_check -s exit:0 su -fm $uidoutrange -c "$command1"
134}
135subject_match_on_gid_cleanup()
136{
137	cleanup
138}
139
140atf_test_case subject_match_on_jail cleanup
141subject_match_on_jail_head()
142{
143	atf_set "require.progs" "jail"
144	atf_set "require.user" "root"
145}
146subject_match_on_jail_body()
147{
148	setup
149
150	atf_expect_fail "this testcase fails (see bug # 205481)"
151	# subject matching jailid
152	jailid=`jail -i / localhost 127.0.0.1 /usr/sbin/daemon -f /bin/sh -c "(sleep 5; touch mnt/test-jail) &"`
153	atf_check -s exit:0 ugidfw set 1 subject jailid $jailid object mode rasx
154	sleep 10
155
156	if [ -f mnt/test-jail ]; then
157		atf_fail "$desc"
158	fi
159
160	rm -f mnt/test-jail
161	# subject nonmatching jailid
162	jailid=`jail -i / localhost 127.0.0.1 /usr/sbin/daemon -f /bin/sh -c "(sleep 5; touch mnt/test-jail) &"`
163	sleep 10
164	if ! [ -f mnt/test-jail ]; then
165		atf_fail $desc
166	fi
167}
168subject_match_on_jail_cleanup()
169{
170	cleanup
171}
172
173atf_test_case object_uid cleanup
174object_uid_head()
175{
176	atf_set "require.user" "root"
177}
178object_uid_body()
179{
180	setup
181
182	atf_check -s exit:0 ugidfw set 1 subject object uid $uidrange mode rasx
183
184	# object uid in range
185	atf_check -s not-exit:0 -e match:"Permission denied" \
186		su -fm $uidinrange -c "$command1"
187
188	# object uid out range
189	atf_check -s exit:0 su -fm $uidinrange -c "$command2"
190	atf_check -s exit:0 ugidfw set 1 subject object uid $uidrange mode rasx
191
192	# object uid in range (different subject)
193	atf_check -s not-exit:0 -e match:"Permission denied" \
194		su -fm $uidoutrange -c "$command1"
195
196	# object uid out range (different subject)
197	atf_check -s exit:0 su -fm $uidoutrange -c "$command2"
198
199}
200object_uid_cleanup()
201{
202	cleanup
203}
204
205atf_test_case object_gid cleanup
206object_gid_head()
207{
208	atf_set "require.user" "root"
209}
210object_gid_body()
211{
212	setup
213
214	atf_check -s exit:0 ugidfw set 1 subject object gid $uidrange mode rasx
215
216	# object gid in range
217	atf_check -s not-exit:0 -e match:"Permission denied" \
218		su -fm $uidinrange -c "$command1"
219
220	# object gid out range
221	atf_check -s exit:0 su -fm $uidinrange -c "$command2"
222	# object gid in range (different subject)
223	atf_check -s not-exit:0 -e match:"Permission denied" \
224		su -fm $uidoutrange -c "$command1"
225
226	# object gid out range (different subject)
227	atf_check -s exit:0 su -fm $uidoutrange -c "$command2"
228}
229object_gid_cleanup()
230{
231	cleanup
232}
233
234atf_test_case object_filesys cleanup
235object_filesys_head()
236{
237	atf_set "require.user" "root"
238}
239object_filesys_body()
240{
241	setup
242
243	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object filesys / mode rasx
244	# object out of filesys
245	atf_check -s exit:0 su -fm $uidinrange -c "$command1"
246
247	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object filesys mnt mode rasx
248	# object in filesys
249	atf_check -s not-exit:0 -e match:"Permission denied" \
250		su -fm $uidinrange -c "$command1"
251}
252object_filesys_cleanup()
253{
254	cleanup
255}
256
257atf_test_case object_suid cleanup
258object_suid_head()
259{
260	atf_set "require.user" "root"
261}
262object_suid_body()
263{
264	setup
265
266	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object suid mode rasx
267	# object notsuid
268	atf_check -s exit:0 su -fm $uidinrange -c "$command1"
269
270	chmod u+s $file1
271	# object suid
272	atf_check -s not-exit:0 -e match:"Permission denied" \
273		su -fm $uidinrange -c "$command1"
274	chmod u-s $file1
275
276}
277object_suid_cleanup()
278{
279	cleanup
280}
281
282atf_test_case object_sgid cleanup
283object_sgid_head()
284{
285	atf_set "require.user" "root"
286}
287object_sgid_body()
288{
289	setup
290
291	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object sgid mode rasx
292	# object notsgid
293	atf_check -s exit:0 su -fm $uidinrange -c "$command1"
294
295	chmod g+s $file1
296	# object sgid
297	atf_check -s not-exit:0 -e match:"Permission denied" \
298		su -fm $uidinrange -c "$command1"
299	chmod g-s $file1
300}
301object_sgid_cleanup()
302{
303	cleanup
304}
305
306atf_test_case object_uid_matches_subject cleanup
307object_uid_matches_subject_head()
308{
309	atf_set "require.user" "root"
310}
311object_uid_matches_subject_body()
312{
313	setup
314
315	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object uid_of_subject mode rasx
316
317	# object uid notmatches subject
318	atf_check -s exit:0 su -fm $uidinrange -c "$command2"
319
320	# object uid matches subject
321	atf_check -s not-exit:0 -e match:"Permission denied" \
322		su -fm $uidinrange -c "$command1"
323}
324object_uid_matches_subject_cleanup()
325{
326	cleanup
327}
328
329atf_test_case object_gid_matches_subject cleanup
330object_gid_matches_subject_head()
331{
332	atf_set "require.user" "root"
333}
334object_gid_matches_subject_body()
335{
336	setup
337
338	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object gid_of_subject mode rasx
339
340	# object gid notmatches subject
341	atf_check -s exit:0 su -fm $uidinrange -c "$command2"
342
343	# object gid matches subject
344	atf_check -s not-exit:0 -e match:"Permission denied" \
345		su -fm $uidinrange -c "$command1"
346
347}
348object_gid_matches_subject_cleanup()
349{
350	cleanup
351}
352
353atf_test_case object_type cleanup
354object_type_head()
355{
356	atf_set "require.user" "root"
357}
358object_type_body()
359{
360	setup
361
362	# object not type
363	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object type dbclsp mode rasx
364	atf_check -s exit:0 su -fm $uidinrange -c "$command1"
365
366	# object type
367	atf_check -s exit:0 ugidfw set 1 subject uid $uidrange object type r mode rasx
368	atf_check -s not-exit:0 -e match:"Permission denied" \
369		su -fm $uidinrange -c "$command1"
370}
371object_type_cleanup()
372{
373	cleanup
374}
375
376atf_init_test_cases()
377{
378	atf_add_test_case no_rules
379	atf_add_test_case subject_match_on_uid
380	atf_add_test_case subject_match_on_gid
381	atf_add_test_case subject_match_on_jail
382	atf_add_test_case object_uid
383	atf_add_test_case object_gid
384	atf_add_test_case object_filesys
385	atf_add_test_case object_suid
386	atf_add_test_case object_sgid
387	atf_add_test_case object_uid_matches_subject
388	atf_add_test_case object_gid_matches_subject
389	atf_add_test_case object_type
390}
391