Home | History | Annotate | Line # | Download | only in puffs
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