t_fuzz.c revision 1.4 1 1.4 pooka /* $NetBSD: t_fuzz.c,v 1.4 2010/08/27 12:42:21 pooka Exp $ */
2 1.1 pooka
3 1.1 pooka /*-
4 1.1 pooka * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.1 pooka * All rights reserved.
6 1.1 pooka *
7 1.1 pooka * Redistribution and use in source and binary forms, with or without
8 1.1 pooka * modification, are permitted provided that the following conditions
9 1.1 pooka * are met:
10 1.1 pooka * 1. Redistributions of source code must retain the above copyright
11 1.1 pooka * notice, this list of conditions and the following disclaimer.
12 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 pooka * notice, this list of conditions and the following disclaimer in the
14 1.1 pooka * documentation and/or other materials provided with the distribution.
15 1.1 pooka *
16 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 pooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 pooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 pooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 pooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 pooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 pooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 pooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 pooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 pooka * POSSIBILITY OF SUCH DAMAGE.
27 1.1 pooka */
28 1.1 pooka
29 1.1 pooka /*
30 1.1 pooka * Fuzztest puffs mount. There are n different levels of testing:
31 1.1 pooka * each one pours more and more sane garbage into the args to that
32 1.1 pooka * the mount progresses further and further. Level 8 (at least when
33 1.1 pooka * writing this comment) should be the one where mounting actually
34 1.1 pooka * succeeds.
35 1.1 pooka *
36 1.1 pooka * Our metric of success is crash / no crash.
37 1.1 pooka */
38 1.1 pooka
39 1.1 pooka #include <sys/types.h>
40 1.1 pooka #include <sys/mount.h>
41 1.4 pooka #include <sys/poll.h>
42 1.1 pooka
43 1.1 pooka #include <assert.h>
44 1.1 pooka #include <atf-c.h>
45 1.1 pooka #include <err.h>
46 1.1 pooka #include <errno.h>
47 1.1 pooka #include <fcntl.h>
48 1.1 pooka #include <pthread.h>
49 1.1 pooka #include <stdio.h>
50 1.1 pooka #include <unistd.h>
51 1.1 pooka #include <string.h>
52 1.1 pooka #include <stdlib.h>
53 1.1 pooka
54 1.1 pooka #include <fs/puffs/puffs_msgif.h>
55 1.1 pooka
56 1.1 pooka #include <rump/rump.h>
57 1.1 pooka #include <rump/rump_syscalls.h>
58 1.1 pooka
59 1.1 pooka #include "../../h_macros.h"
60 1.1 pooka
61 1.1 pooka #define ITERATIONS 100
62 1.1 pooka
63 1.1 pooka static void
64 1.1 pooka fixversion(struct puffs_kargs *kargs)
65 1.1 pooka {
66 1.1 pooka
67 1.1 pooka kargs->pa_vers = PUFFSVERSION;
68 1.1 pooka }
69 1.1 pooka
70 1.1 pooka static void
71 1.1 pooka fixkflag(struct puffs_kargs *kargs)
72 1.1 pooka {
73 1.1 pooka
74 1.1 pooka kargs->pa_flags &= PUFFS_KFLAG_MASK;
75 1.1 pooka }
76 1.1 pooka
77 1.1 pooka static void
78 1.1 pooka fixfhflag(struct puffs_kargs *kargs)
79 1.1 pooka {
80 1.1 pooka
81 1.1 pooka kargs->pa_fhflags &= PUFFS_FHFLAG_MASK;
82 1.1 pooka }
83 1.1 pooka
84 1.1 pooka static void
85 1.1 pooka fixspare(struct puffs_kargs *kargs)
86 1.1 pooka {
87 1.1 pooka
88 1.1 pooka memset(&kargs->pa_spare, 0, sizeof(kargs->pa_spare));
89 1.1 pooka }
90 1.1 pooka
91 1.1 pooka static void
92 1.1 pooka fixhandsize(struct puffs_kargs *kargs)
93 1.1 pooka {
94 1.1 pooka
95 1.1 pooka kargs->pa_fhsize %= PUFFS_FHSIZE_MAX+4;
96 1.1 pooka }
97 1.1 pooka
98 1.1 pooka static void
99 1.1 pooka fixhandsize2(struct puffs_kargs *kargs)
100 1.1 pooka {
101 1.1 pooka
102 1.1 pooka /* XXX: values */
103 1.1 pooka if (kargs->pa_fhflags & PUFFS_FHFLAG_NFSV3)
104 1.1 pooka kargs->pa_fhsize %= 60;
105 1.1 pooka if (kargs->pa_fhflags & PUFFS_FHFLAG_NFSV2)
106 1.1 pooka kargs->pa_fhsize %= 28;
107 1.1 pooka }
108 1.1 pooka
109 1.1 pooka static void
110 1.1 pooka fixputter(struct puffs_kargs *kargs)
111 1.1 pooka {
112 1.1 pooka
113 1.1 pooka kargs->pa_fd = rump_sys_open("/dev/putter", O_RDWR);
114 1.1 pooka if (kargs->pa_fd == -1)
115 1.1 pooka atf_tc_fail_errno("open putter");
116 1.1 pooka }
117 1.1 pooka
118 1.1 pooka static void
119 1.1 pooka fixroot(struct puffs_kargs *kargs)
120 1.1 pooka {
121 1.1 pooka
122 1.1 pooka kargs->pa_root_vtype %= VBAD;
123 1.1 pooka }
124 1.1 pooka
125 1.1 pooka static void
126 1.1 pooka unfixputter(struct puffs_kargs *kargs)
127 1.1 pooka {
128 1.1 pooka
129 1.1 pooka rump_sys_close(kargs->pa_fd);
130 1.1 pooka }
131 1.1 pooka
132 1.1 pooka typedef void (*fixfn)(struct puffs_kargs *);
133 1.1 pooka static fixfn fixstack[] = {
134 1.1 pooka fixversion,
135 1.1 pooka fixkflag,
136 1.1 pooka fixfhflag,
137 1.1 pooka fixspare,
138 1.1 pooka fixhandsize,
139 1.1 pooka fixhandsize2,
140 1.1 pooka fixputter,
141 1.1 pooka fixroot,
142 1.1 pooka };
143 1.1 pooka
144 1.1 pooka static void
145 1.1 pooka fixup(int nfix, struct puffs_kargs *kargs)
146 1.1 pooka {
147 1.1 pooka int i;
148 1.1 pooka
149 1.1 pooka assert(nfix <= __arraycount(fixstack));
150 1.1 pooka for (i = 0; i < nfix; i++)
151 1.1 pooka fixstack[i](kargs);
152 1.1 pooka }
153 1.1 pooka
154 1.1 pooka static void
155 1.1 pooka unfixup(int nfix, struct puffs_kargs *kargs)
156 1.1 pooka {
157 1.1 pooka
158 1.1 pooka if (nfix >= 7)
159 1.1 pooka unfixputter(kargs);
160 1.1 pooka }
161 1.1 pooka
162 1.1 pooka static pthread_mutex_t damtx;
163 1.1 pooka static pthread_cond_t dacv;
164 1.1 pooka static int dafd = -1;
165 1.1 pooka
166 1.1 pooka static void *
167 1.1 pooka respondthread(void *arg)
168 1.1 pooka {
169 1.1 pooka char buf[PUFFS_MSG_MAXSIZE];
170 1.1 pooka struct puffs_req *preq = (void *)buf;
171 1.4 pooka struct pollfd pfd;
172 1.1 pooka ssize_t n;
173 1.1 pooka
174 1.1 pooka pthread_mutex_lock(&damtx);
175 1.1 pooka for (;;) {
176 1.1 pooka while (dafd == -1)
177 1.1 pooka pthread_cond_wait(&dacv, &damtx);
178 1.1 pooka
179 1.1 pooka while (dafd != -1) {
180 1.1 pooka pthread_mutex_unlock(&damtx);
181 1.4 pooka pfd.fd = dafd;
182 1.4 pooka pfd.events = POLLIN;
183 1.4 pooka pfd.revents = 0;
184 1.4 pooka if (rump_sys_poll(&pfd, 1, 10) == 0) {
185 1.4 pooka pthread_mutex_lock(&damtx);
186 1.4 pooka continue;
187 1.4 pooka }
188 1.1 pooka n = rump_sys_read(dafd, buf, sizeof(buf));
189 1.1 pooka if (n <= 0) {
190 1.1 pooka pthread_mutex_lock(&damtx);
191 1.1 pooka break;
192 1.1 pooka }
193 1.1 pooka
194 1.1 pooka /* just say it was succesful */
195 1.1 pooka preq->preq_rv = 0;
196 1.1 pooka rump_sys_write(dafd, buf, n);
197 1.1 pooka pthread_mutex_lock(&damtx);
198 1.1 pooka }
199 1.1 pooka }
200 1.2 pooka
201 1.2 pooka return NULL;
202 1.1 pooka }
203 1.1 pooka
204 1.1 pooka static void
205 1.1 pooka testbody(int nfix)
206 1.1 pooka {
207 1.1 pooka pthread_t pt;
208 1.1 pooka struct puffs_kargs kargs;
209 1.1 pooka unsigned long seed;
210 1.1 pooka int i;
211 1.1 pooka
212 1.1 pooka seed = time(NULL);
213 1.1 pooka srandom(seed);
214 1.1 pooka printf("test seeded RNG with %lu\n", seed);
215 1.1 pooka
216 1.4 pooka rump_init();
217 1.4 pooka
218 1.1 pooka pthread_mutex_init(&damtx, NULL);
219 1.1 pooka pthread_cond_init(&dacv, NULL);
220 1.1 pooka pthread_create(&pt, NULL, respondthread, NULL);
221 1.1 pooka
222 1.1 pooka ATF_REQUIRE(rump_sys_mkdir("/mnt", 0777) == 0);
223 1.1 pooka
224 1.1 pooka for (i = 0; i < ITERATIONS; i++) {
225 1.3 pooka tests_makegarbage(&kargs, sizeof(kargs));
226 1.1 pooka fixup(nfix, &kargs);
227 1.1 pooka if (rump_sys_mount(MOUNT_PUFFS, "/mnt", 0,
228 1.1 pooka &kargs, sizeof(kargs)) == 0) {
229 1.1 pooka struct stat sb;
230 1.1 pooka
231 1.1 pooka pthread_mutex_lock(&damtx);
232 1.1 pooka dafd = kargs.pa_fd;
233 1.1 pooka pthread_cond_signal(&dacv);
234 1.1 pooka pthread_mutex_unlock(&damtx);
235 1.1 pooka
236 1.1 pooka rump_sys_stat("/mnt", &sb);
237 1.1 pooka rump_sys_unmount("/mnt", MNT_FORCE);
238 1.1 pooka }
239 1.1 pooka unfixup(nfix, &kargs);
240 1.1 pooka
241 1.1 pooka pthread_mutex_lock(&damtx);
242 1.1 pooka dafd = -1;
243 1.1 pooka pthread_mutex_unlock(&damtx);
244 1.1 pooka }
245 1.1 pooka }
246 1.1 pooka
247 1.1 pooka #define MAKETEST(_n_) \
248 1.1 pooka ATF_TC(mountfuzz##_n_); \
249 1.1 pooka ATF_TC_HEAD(mountfuzz##_n_, tc) \
250 1.3 pooka {atf_tc_set_md_var(tc, "descr", "garbage kargs, " # _n_ " fix(es)");} \
251 1.1 pooka ATF_TC_BODY(mountfuzz##_n_, tc) {testbody(_n_);}
252 1.1 pooka
253 1.1 pooka MAKETEST(0);
254 1.1 pooka MAKETEST(1);
255 1.1 pooka MAKETEST(2);
256 1.1 pooka MAKETEST(3);
257 1.1 pooka MAKETEST(4);
258 1.1 pooka MAKETEST(5);
259 1.1 pooka MAKETEST(6);
260 1.1 pooka MAKETEST(7);
261 1.1 pooka MAKETEST(8);
262 1.1 pooka
263 1.1 pooka ATF_TP_ADD_TCS(tp)
264 1.1 pooka {
265 1.1 pooka
266 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz0);
267 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz1);
268 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz2);
269 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz3);
270 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz4);
271 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz5);
272 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz6);
273 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz7);
274 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz8);
275 1.1 pooka
276 1.1 pooka return atf_no_error();
277 1.1 pooka }
278