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