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