xref: /freebsd/tests/sys/acl/aclfuzzer.sh (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1#!/bin/sh
2#
3# Copyright (c) 2008, 2009 Edward Tomasz Napierała <trasz@FreeBSD.org>
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24# SUCH DAMAGE.
25#
26#
27
28# This is an NFSv4 ACL fuzzer.  It expects to be run by non-root in a scratch
29# directory on a filesystem with NFSv4 ACLs support.  Output it generates
30# is expected to be fed to /usr/src/tools/regression/acltools/run script.
31
32NUMBER_OF_COMMANDS=300
33
34run_command()
35{
36	echo "\$ $1"
37	eval $1 2>&1 | sed 's/^/> /'
38}
39
40rnd_from_0_to()
41{
42	max=`expr $1 + 1`
43	rnd=`jot -r 1`
44	rnd=`expr $rnd % $max`
45
46	echo $rnd
47}
48
49rnd_path()
50{
51	rnd=`rnd_from_0_to 3`
52	case $rnd in
53		0) echo "$TMP/aaa" ;;
54		1) echo "$TMP/bbb" ;;
55		2) echo "$TMP/aaa/ccc" ;;
56		3) echo "$TMP/bbb/ddd" ;;
57	esac
58}
59
60f_prepend_random_acl_on()
61{
62	rnd=`rnd_from_0_to 4`
63	case $rnd in
64		0) u="owner@" ;;
65		1) u="group@" ;;
66		2) u="everyone@" ;;
67		3) u="u:1138" ;;
68		4) u="g:1138" ;;
69	esac
70
71	p=""
72	while :; do
73		rnd=`rnd_from_0_to 30`
74		if [ -n "$p" -a $rnd -ge 14 ]; then
75			break;
76		fi
77
78		case $rnd in
79			0) p="${p}r" ;;
80			1) p="${p}w" ;;
81			2) p="${p}x" ;;
82			3) p="${p}p" ;;
83			4) p="${p}d" ;;
84			5) p="${p}D" ;;
85			6) p="${p}a" ;;
86			7) p="${p}A" ;;
87			8) p="${p}R" ;;
88			9) p="${p}W" ;;
89			10) p="${p}R" ;;
90			11) p="${p}c" ;;
91			12) p="${p}C" ;;
92			13) p="${p}o" ;;
93			14) p="${p}s" ;;
94		esac
95	done
96
97	f=""
98	while :; do
99		rnd=`rnd_from_0_to 10`
100		if [ $rnd -ge 6 ]; then
101			break;
102		fi
103
104		case $rnd in
105			0) f="${f}f" ;;
106			1) f="${f}d" ;;
107			2) f="${f}n" ;;
108			3) f="${f}i" ;;
109		esac
110	done
111
112	rnd=`rnd_from_0_to 1`
113	case $rnd in
114		0) x="allow" ;;
115		1) x="deny" ;;
116	esac
117
118	acl="$u:$p:$f:$x"
119
120	file=`rnd_path`
121	run_command "setfacl -a0 $acl $file"
122}
123
124f_getfacl()
125{
126	file=`rnd_path`
127	run_command "getfacl -qn $file"
128}
129
130f_ls_mode()
131{
132	file=`rnd_path`
133	run_command "ls -al $file | sed -n '2p' | cut -d' ' -f1"
134}
135
136f_chmod()
137{
138	b1=`rnd_from_0_to 7`
139	b2=`rnd_from_0_to 7`
140	b3=`rnd_from_0_to 7`
141	b4=`rnd_from_0_to 7`
142	file=`rnd_path`
143
144	run_command "chmod $b1$b2$b3$b4 $file $2"
145}
146
147f_touch()
148{
149	file=`rnd_path`
150	run_command "touch $file"
151}
152
153f_rm()
154{
155	file=`rnd_path`
156	run_command "rm -f $file"
157}
158
159f_mkdir()
160{
161	file=`rnd_path`
162	run_command "mkdir $file"
163}
164
165f_rmdir()
166{
167	file=`rnd_path`
168	run_command "rmdir $file"
169}
170
171f_mv()
172{
173	from=`rnd_path`
174	to=`rnd_path`
175	run_command "mv -f $from $to"
176}
177
178# XXX: To be implemented: chown(8), setting times with touch(1).
179
180switch_to_random_user()
181{
182	# XXX: To be implemented.
183}
184
185execute_random_command()
186{
187	rnd=`rnd_from_0_to 20`
188
189	case $rnd in
190		0|10|11|12|13|15) cmd=f_prepend_random_acl_on ;;
191		1) cmd=f_getfacl ;;
192		2) cmd=f_ls_mode ;;
193		3) cmd=f_chmod ;;
194		4|18|19) cmd=f_touch ;;
195		5) cmd=f_rm ;;
196		6|16|17) cmd=f_mkdir ;;
197		7) cmd=f_rmdir ;;
198		8) cmd=f_mv ;;
199	esac
200
201	$cmd "XXX"
202}
203
204echo "# Fuzzing; will stop after $NUMBER_OF_COMMANDS commands."
205TMP="aclfuzzer_`dd if=/dev/random bs=1k count=1 2>/dev/null | openssl md5`"
206
207run_command "whoami"
208umask 022
209run_command "umask 022"
210run_command "mkdir $TMP"
211
212i=0;
213while [ "$i" -lt "$NUMBER_OF_COMMANDS" ]; do
214	switch_to_random_user
215	execute_random_command
216	i=`expr $i + 1`
217done
218
219run_command "find $TMP -exec setfacl -a0 everyone@:rxd:allow {} \;"
220run_command "rm -rfv $TMP"
221
222echo "# Fuzzed, thank you."
223
224