t_fuzz.c revision 1.3 1 1.3 pooka /* $NetBSD: t_fuzz.c,v 1.3 2010/08/16 10:46:20 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.1 pooka
42 1.1 pooka #include <assert.h>
43 1.1 pooka #include <atf-c.h>
44 1.1 pooka #include <err.h>
45 1.1 pooka #include <errno.h>
46 1.1 pooka #include <fcntl.h>
47 1.1 pooka #include <pthread.h>
48 1.1 pooka #include <stdio.h>
49 1.1 pooka #include <unistd.h>
50 1.1 pooka #include <string.h>
51 1.1 pooka #include <stdlib.h>
52 1.1 pooka
53 1.1 pooka #include <fs/puffs/puffs_msgif.h>
54 1.1 pooka
55 1.1 pooka #include <rump/rump.h>
56 1.1 pooka #include <rump/rump_syscalls.h>
57 1.1 pooka
58 1.1 pooka #include "../../h_macros.h"
59 1.1 pooka
60 1.1 pooka #define ITERATIONS 100
61 1.1 pooka
62 1.1 pooka static void
63 1.1 pooka fixversion(struct puffs_kargs *kargs)
64 1.1 pooka {
65 1.1 pooka
66 1.1 pooka kargs->pa_vers = PUFFSVERSION;
67 1.1 pooka }
68 1.1 pooka
69 1.1 pooka static void
70 1.1 pooka fixkflag(struct puffs_kargs *kargs)
71 1.1 pooka {
72 1.1 pooka
73 1.1 pooka kargs->pa_flags &= PUFFS_KFLAG_MASK;
74 1.1 pooka }
75 1.1 pooka
76 1.1 pooka static void
77 1.1 pooka fixfhflag(struct puffs_kargs *kargs)
78 1.1 pooka {
79 1.1 pooka
80 1.1 pooka kargs->pa_fhflags &= PUFFS_FHFLAG_MASK;
81 1.1 pooka }
82 1.1 pooka
83 1.1 pooka static void
84 1.1 pooka fixspare(struct puffs_kargs *kargs)
85 1.1 pooka {
86 1.1 pooka
87 1.1 pooka memset(&kargs->pa_spare, 0, sizeof(kargs->pa_spare));
88 1.1 pooka }
89 1.1 pooka
90 1.1 pooka static void
91 1.1 pooka fixhandsize(struct puffs_kargs *kargs)
92 1.1 pooka {
93 1.1 pooka
94 1.1 pooka kargs->pa_fhsize %= PUFFS_FHSIZE_MAX+4;
95 1.1 pooka }
96 1.1 pooka
97 1.1 pooka static void
98 1.1 pooka fixhandsize2(struct puffs_kargs *kargs)
99 1.1 pooka {
100 1.1 pooka
101 1.1 pooka /* XXX: values */
102 1.1 pooka if (kargs->pa_fhflags & PUFFS_FHFLAG_NFSV3)
103 1.1 pooka kargs->pa_fhsize %= 60;
104 1.1 pooka if (kargs->pa_fhflags & PUFFS_FHFLAG_NFSV2)
105 1.1 pooka kargs->pa_fhsize %= 28;
106 1.1 pooka }
107 1.1 pooka
108 1.1 pooka static void
109 1.1 pooka fixputter(struct puffs_kargs *kargs)
110 1.1 pooka {
111 1.1 pooka
112 1.1 pooka kargs->pa_fd = rump_sys_open("/dev/putter", O_RDWR);
113 1.1 pooka if (kargs->pa_fd == -1)
114 1.1 pooka atf_tc_fail_errno("open putter");
115 1.1 pooka }
116 1.1 pooka
117 1.1 pooka static void
118 1.1 pooka fixroot(struct puffs_kargs *kargs)
119 1.1 pooka {
120 1.1 pooka
121 1.1 pooka kargs->pa_root_vtype %= VBAD;
122 1.1 pooka }
123 1.1 pooka
124 1.1 pooka static void
125 1.1 pooka unfixputter(struct puffs_kargs *kargs)
126 1.1 pooka {
127 1.1 pooka
128 1.1 pooka rump_sys_close(kargs->pa_fd);
129 1.1 pooka }
130 1.1 pooka
131 1.1 pooka typedef void (*fixfn)(struct puffs_kargs *);
132 1.1 pooka static fixfn fixstack[] = {
133 1.1 pooka fixversion,
134 1.1 pooka fixkflag,
135 1.1 pooka fixfhflag,
136 1.1 pooka fixspare,
137 1.1 pooka fixhandsize,
138 1.1 pooka fixhandsize2,
139 1.1 pooka fixputter,
140 1.1 pooka fixroot,
141 1.1 pooka };
142 1.1 pooka
143 1.1 pooka static void
144 1.1 pooka fixup(int nfix, struct puffs_kargs *kargs)
145 1.1 pooka {
146 1.1 pooka int i;
147 1.1 pooka
148 1.1 pooka assert(nfix <= __arraycount(fixstack));
149 1.1 pooka for (i = 0; i < nfix; i++)
150 1.1 pooka fixstack[i](kargs);
151 1.1 pooka }
152 1.1 pooka
153 1.1 pooka static void
154 1.1 pooka unfixup(int nfix, struct puffs_kargs *kargs)
155 1.1 pooka {
156 1.1 pooka
157 1.1 pooka if (nfix >= 7)
158 1.1 pooka unfixputter(kargs);
159 1.1 pooka }
160 1.1 pooka
161 1.1 pooka static pthread_mutex_t damtx;
162 1.1 pooka static pthread_cond_t dacv;
163 1.1 pooka static int dafd = -1;
164 1.1 pooka
165 1.1 pooka static void *
166 1.1 pooka respondthread(void *arg)
167 1.1 pooka {
168 1.1 pooka char buf[PUFFS_MSG_MAXSIZE];
169 1.1 pooka struct puffs_req *preq = (void *)buf;
170 1.1 pooka ssize_t n;
171 1.1 pooka
172 1.1 pooka pthread_mutex_lock(&damtx);
173 1.1 pooka for (;;) {
174 1.1 pooka while (dafd == -1)
175 1.1 pooka pthread_cond_wait(&dacv, &damtx);
176 1.1 pooka
177 1.1 pooka while (dafd != -1) {
178 1.1 pooka pthread_mutex_unlock(&damtx);
179 1.1 pooka n = rump_sys_read(dafd, buf, sizeof(buf));
180 1.1 pooka if (n <= 0) {
181 1.1 pooka pthread_mutex_lock(&damtx);
182 1.1 pooka break;
183 1.1 pooka }
184 1.1 pooka
185 1.1 pooka /* just say it was succesful */
186 1.1 pooka preq->preq_rv = 0;
187 1.1 pooka rump_sys_write(dafd, buf, n);
188 1.1 pooka pthread_mutex_lock(&damtx);
189 1.1 pooka }
190 1.1 pooka }
191 1.2 pooka
192 1.2 pooka return NULL;
193 1.1 pooka }
194 1.1 pooka
195 1.1 pooka static void
196 1.1 pooka testbody(int nfix)
197 1.1 pooka {
198 1.1 pooka pthread_t pt;
199 1.1 pooka struct puffs_kargs kargs;
200 1.1 pooka unsigned long seed;
201 1.1 pooka int i;
202 1.1 pooka
203 1.1 pooka seed = time(NULL);
204 1.1 pooka srandom(seed);
205 1.1 pooka printf("test seeded RNG with %lu\n", seed);
206 1.1 pooka
207 1.1 pooka pthread_mutex_init(&damtx, NULL);
208 1.1 pooka pthread_cond_init(&dacv, NULL);
209 1.1 pooka pthread_create(&pt, NULL, respondthread, NULL);
210 1.1 pooka
211 1.1 pooka rump_init();
212 1.1 pooka ATF_REQUIRE(rump_sys_mkdir("/mnt", 0777) == 0);
213 1.1 pooka
214 1.1 pooka for (i = 0; i < ITERATIONS; i++) {
215 1.3 pooka tests_makegarbage(&kargs, sizeof(kargs));
216 1.1 pooka fixup(nfix, &kargs);
217 1.1 pooka if (rump_sys_mount(MOUNT_PUFFS, "/mnt", 0,
218 1.1 pooka &kargs, sizeof(kargs)) == 0) {
219 1.1 pooka struct stat sb;
220 1.1 pooka
221 1.1 pooka pthread_mutex_lock(&damtx);
222 1.1 pooka dafd = kargs.pa_fd;
223 1.1 pooka pthread_cond_signal(&dacv);
224 1.1 pooka pthread_mutex_unlock(&damtx);
225 1.1 pooka
226 1.1 pooka rump_sys_stat("/mnt", &sb);
227 1.1 pooka rump_sys_unmount("/mnt", MNT_FORCE);
228 1.1 pooka }
229 1.1 pooka unfixup(nfix, &kargs);
230 1.1 pooka
231 1.1 pooka pthread_mutex_lock(&damtx);
232 1.1 pooka dafd = -1;
233 1.1 pooka pthread_mutex_unlock(&damtx);
234 1.1 pooka }
235 1.1 pooka }
236 1.1 pooka
237 1.1 pooka #define MAKETEST(_n_) \
238 1.1 pooka ATF_TC(mountfuzz##_n_); \
239 1.1 pooka ATF_TC_HEAD(mountfuzz##_n_, tc) \
240 1.3 pooka {atf_tc_set_md_var(tc, "descr", "garbage kargs, " # _n_ " fix(es)");} \
241 1.1 pooka ATF_TC_BODY(mountfuzz##_n_, tc) {testbody(_n_);}
242 1.1 pooka
243 1.1 pooka MAKETEST(0);
244 1.1 pooka MAKETEST(1);
245 1.1 pooka MAKETEST(2);
246 1.1 pooka MAKETEST(3);
247 1.1 pooka MAKETEST(4);
248 1.1 pooka MAKETEST(5);
249 1.1 pooka MAKETEST(6);
250 1.1 pooka MAKETEST(7);
251 1.1 pooka MAKETEST(8);
252 1.1 pooka
253 1.1 pooka ATF_TP_ADD_TCS(tp)
254 1.1 pooka {
255 1.1 pooka
256 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz0);
257 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz1);
258 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz2);
259 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz3);
260 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz4);
261 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz5);
262 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz6);
263 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz7);
264 1.1 pooka ATF_TP_ADD_TC(tp, mountfuzz8);
265 1.1 pooka
266 1.1 pooka return atf_no_error();
267 1.1 pooka }
268