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