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