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