ref: bca057e3578a3fab0e7a0e8346a631e598c5b3f4
author: Steven Sleder <[email protected]>
date: Sun Nov 25 03:17:44 EST 2018
Hacked together a working mut_chararr
--- /dev/null
+++ b/.hgignore
@@ -1,0 +1,4 @@
+syntax: glob
+fuzz.log
+*.[8qkv5967o]
+[8qkv5967o].out
--- /dev/null
+++ b/LICENSE
@@ -1,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Sean Hinchee, Steven Sleder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,45 @@
+# Fuzz -- A kernel fuzzer from Plan 9 space
+
+## Dependencies
+
+fuzz(1) is tested on the [9front](http://9front.org) operating system and as such uses its libraries and runs against its kernels.
+
+Theoretically fuzz could be ported to unix using [plan9port](https://github.com/9fans/plan9port), but this would require a Plan 9 kernel in user space which doesn't really exist outside of [9vx](https://swtch.com/9vx/) which is untested in this regard.
+
+## Building
+
+ mk
+
+## Installing
+
+ mk install
+
+## Building in debug mode
+
+ mk debug
+
+## Usage
+
+To perform up to round 5 of fuzzing for the read, write, open, and close calls:
+
+ fuzz -n 5 read write open close
+
+A list of all known system call names can be printed:
+
+ fuzz ?
+
+## Recommended reading for further development
+
+- http://doc.cat-v.org/plan_9/4th_edition/papers/comp
+- http://doc.cat-v.org/plan_9/programming/c_programming_in_plan_9
+- https://lsub.org/who/nemo/9.pdf
+ - http://9.postnix.us/hist/3e/plan9_3e_kernel.tgz
+- http://doc.cat-v.org/plan_9/misc/adding_a_syscall_to_plan_9/plan9_syscall_howto.pdf
+- http://aiju.de/plan_9/plan9-syscalls
+- http://man.cat-v.org/9front/2/intro
+- http://man.cat-v.org/9front/1/syscall
+ - http://mirror.postnix.us/plan9front/sys/src/cmd/syscall/
+- http://mirror.postnix.us/plan9front/sys/src/libc/9syscall/
+- http://lsub.org/who/nemo/9.intro.pdf
+- http://fxr.watson.org/fxr/source/?v=PLAN9
+
--- /dev/null
+++ b/fuzz.h
@@ -1,0 +1,173 @@
+#ifndef FUZZ_H
+#define FUZZ_H
+
+#include <u.h>
+#include <libc.h>
+#include "list.h"
+#include "mutate.h"
+
+
+// Max signed int value
+#define MAXINT 2147483647
+
+// Number of calls in enum calls
+#define NCALLS 67
+#define NTYPES 16
+
+// Global variables
+// In main.c
+extern int logfd;
+extern Lock loglck;
+extern Lock rnglck;
+
+/*
+For full list of syscalls:
+
+If systab doesn't exist, do: cd /sys/src/9/port && mk
+/sys/src/9/port/systab.h
+/sys/src/libc/9syscall/sys.h
+/sys/include/libc.h:537
+*/
+
+// User space syscall definitions as per libc.h with sc_ prefix added
+typedef int call;
+enum call {
+sc__exits, // unused -- here for offset
+sc_abort , // abort(void);
+sc_access , // access(char*, int);
+sc_alarm , // alarm(ulong);
+sc_await , // await(char*, int);
+sc_bind , // bind(char*, char*, int);
+sc_brk , // brk(void*);
+sc_chdir , // chdir(char*);
+sc_close , // close(int);
+sc_create , // create(char*, int, ulong);
+sc_dup , // dup(int, int);
+sc_errstr , // errstr(char*, uint);
+sc_exec , // exec(char*, char*[]);
+sc_execl , // execl(char*, ...);
+sc_exits , // _exits(char*); // unused
+sc_fork , // fork(void);
+sc_rfork , // rfork(int);
+sc_fauth , // fauth(int, char*);
+sc_fstat , // fstat(int, uchar*, int);
+sc_fwstat , // fwstat(int, uchar*, int);
+sc_fversion, // fversion(int, int, char*, int);
+sc_mount , // mount(int, int, char*, int, char*);
+sc_unmount, // unmount(char*, char*);
+sc_noted , // noted(int);
+sc_notify , // notify(void(*)(void*, char*));
+sc_open , // open(char*, int);
+sc_fd2path, // fd2path(int, char*, int);
+sc_pipe , // pipe(int*);
+sc_pread , // pread(int, void*, long, vlong);
+sc_preadv, // preadv(int, IOchunk*, int, vlong);
+sc_pwrite , // pwrite(int, void*, long, vlong);
+sc_pwritev, // pwritev(int, IOchunk*, int, vlong);
+sc_read , // read(int, void*, long);
+sc_readn , // readn(int, void*, long);
+sc_readv , // readv(int, IOchunk*, int);
+sc_remove, // remove(char*);
+sc_sbrk , // sbrk(ulong);
+sc_oseek , // oseek(int, long, int);
+sc_seek, // seek(int, vlong, int);
+sc_segattach, // segattach(int, char*, void*, ulong);
+sc_segbrk , // segbrk(void*, void*);
+sc_segdetach, // segdetach(void*);
+sc_segflush, // segflush(void*, ulong);
+sc_segfree, // segfree(void*, ulong);
+sc_semacquire, // semacquire(long*, int);
+sc_semrelease, // semrelease(long*, long);
+sc_sleep, // sleep(long);
+sc_stat, // stat(char*, uchar*, int);
+sc_tsemacquire, // tsemacquire(long*, ulong);
+sc_wait, // wait(void);
+sc_waitpid, // waitpid(void);
+sc_write, // write(int, void*, long);
+sc_writev, // writev(int, IOchunk*, int);
+sc_wstat, // wstat(char*, uchar*, int);
+sc_rendezvous, // rendezvous(void*, void*);
+sc_dirstat, // dirstat(char*);
+sc_dirfstat, // dirfstat(int);
+sc_dirwstat, // dirwstat(char*, Dir*);
+sc_dirfwstat, // dirfwstat(int, Dir*);
+sc_dirread, // dirread(int, Dir**);
+sc_nulldir, // nulldir(Dir*);
+sc_dirreadall, // dirreadall(int, Dir**);
+sc_getpid , // getpid(void);
+sc_getppid, // getppid(void);
+sc_rerrstr, // rerrstr(char*, uint);
+sc_sysname, // sysname(void);
+sc_werrstr // werrstr(char*, ...);
+};
+
+// Enum to track types of inputs
+typedef int type;
+enum type {
+t_int, // int
+t_intS, // int pointer
+t_uint, // unsigned int
+t_IOchunkS, // IOChunkS pointer
+t_long, // long
+t_longS, // long pointer
+t_ulong, // unsigned long
+t_vlong, // long long
+t_DirS, // directory pointer
+t_DirSS, // director pointer to string of chars
+t_char, // char
+t_uchar, // unsigned char
+t_ucharS, // unsigned char pointer
+t_charS, // string
+t_charSArr, // char pointer array
+t_void, // void type
+t_voidS // void pointer type
+};
+
+// Structure to track an instance of a given type
+typedef struct t_type t_type;
+struct t_type
+{
+ void* var; // Variable to track
+ type t; // Type of the variable to cast to
+};
+
+// Type names table -- in input.c
+extern char *typenames[NTYPES];
+
+// User space system call names table -- NCALLS length -- in input.c
+extern char *callnames[NCALLS];
+
+// Structure to track state of system calling
+typedef struct caller caller;
+struct caller
+{
+ call c; // System call in use
+ char* name; // Real name of syscall
+ int round; // Last run executed
+ int seed; // Seed call was initialized with
+ List inputs; // List of input types in order from left→right
+};
+
+// Index of system calls -- one for each enum'd system call
+caller syscalls[NCALLS];
+
+/* == Function prototypes == */
+
+// input.c
+void fuzz(caller*);
+void hjsync(void);
+void log_call(caller*);
+
+// inlist.c
+List* mkinlist(List*, call);
+
+// list.c → See list.h
+
+// mutate.c → See mutate.h
+
+// main.c
+void dolog(char*, ...);
+void debug(char*, ...);
+int rng(void);
+
+#endif
--- /dev/null
+++ b/fuzz.man
@@ -1,0 +1,51 @@
+.TH FUZZ 1
+
+.SH NAME
+fuzz \- kernel fuzzer from Plan 9 space
+
+.SH SYNOPSIS
+.B fuzz
+[
+.B -n
+.I rounds
+]
+.B call …
+
+.SH DESCRIPTION
+.I Fuzz
+
+.PP
+The options are:
+.PD
+
+.TP
+.B -n \fIrounds
+Perform fuzzing for \fIrounds\fR iterations.
+
+.PP
+.SH EXAMPLES
+
+To print all system calls known by fuzz:
+.EX
+fuzz ?
+.EE
+
+To fuzz the read and write system calls for two rounds:
+.EX
+fuzz -n 2 read write
+.EE
+
+.PP
+.SH SOURCE
+.B https://bitbucket.org/cpre43121/fuzz-c
+
+.PP
+.SH "SEE ALSO"
+.IR intro (2),
+.IR syscall (1)
+
+.PP
+.SH BUGS
+
+Oh yeah.
+
--- /dev/null
+++ b/inlist.c
@@ -1,0 +1,437 @@
+#include "fuzz.h"
+
+// HERE BE DRAGONS -- this should be moved to a generator
+// Generate the input list for the given syscall
+
+void mk_int(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(int));
+ *(int *)tt->var = 0;
+ tt->t = t_int;
+
+ ladd(l, tt);
+}
+
+void mk_intS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_intS;
+
+ ladd(l, tt);
+}
+
+void mk_uint(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(unsigned int));
+ *(unsigned int *)tt->var = 0;
+ tt->t = t_uint;
+
+ ladd(l, tt);
+}
+
+void mk_IOchunkS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_IOchunkS;
+
+ ladd(l, tt);
+}
+
+void mk_long(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(long));
+ *(long *)tt->var = 0;
+ tt->t = t_long;
+
+ ladd(l, tt);
+}
+
+void mk_longS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_longS;
+
+ ladd(l, tt);
+}
+
+void mk_ulong(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(unsigned long));
+ *(unsigned long *)tt->var = 0;
+ tt->t = t_ulong;
+
+ ladd(l, tt);
+}
+
+void mk_vlong(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(long long));
+ *(long long *)tt->var = 0;
+ tt->t = t_vlong;
+
+ ladd(l, tt);
+}
+
+void mk_DirS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_DirS;
+
+ ladd(l, tt);
+}
+
+void mk_DirSS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_DirSS;
+
+ ladd(l, tt);
+}
+
+void mk_char(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(char));
+ *(char *)tt->var = '\n';
+ tt->t = t_char;
+
+ ladd(l, tt);
+}
+
+void mk_uchar(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(sizeof(unsigned char));
+ *(unsigned char *)tt->var = '\n';
+ tt->t = t_uchar;
+
+ ladd(l, tt);
+}
+
+void mk_ucharS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_ucharS;
+
+ ladd(l, tt);
+}
+
+void mk_charS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = malloc(1* sizeof(char*));
+ tt->t = t_charS;
+
+ ladd(l, tt);
+}
+
+void mk_void(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_void;
+
+ ladd(l, tt);
+}
+
+void mk_voidS(List *l)
+{
+ t_type *tt = malloc(sizeof(t_type));
+ tt->var = nil;
+ tt->t = t_voidS;
+
+ ladd(l, tt);
+}
+
+List*
+mkinlist(List* l, call c)
+{
+ // Iterate through l
+
+ switch(c){
+ case sc_abort:
+ mk_void(l);
+ break;
+ case sc_access:
+ mk_charS(l);
+ mk_int(l);
+ break;
+ case sc_alarm:
+ mk_ulong(l);
+ break;
+ case sc_await:
+ mk_charS(l);
+ mk_int(l);
+ break;
+ case sc_bind:
+ mk_charS(l);
+ mk_charS(l);
+ mk_int(l);
+ break;
+ case sc_brk:
+ mk_voidS(l);
+ break;
+ case sc_chdir:
+ mk_charS(l);
+ break;
+ case sc_close:
+ mk_int(l);
+ break;
+ case sc_create:
+ mk_charS(l);
+ mk_int(l);
+ mk_ulong(l);
+ break;
+ case sc_dup:
+ mk_int(l);
+ mk_int(l);
+ break;
+ case sc_errstr:
+ mk_charS(l);
+ mk_uint(l);
+ break;
+ case sc_exec:
+
+ // wtf?
+
+ break;
+ case sc_execl:
+ mk_charS(l);
+ break;
+ case sc_exits:
+ mk_charS(l);
+ break;
+ case sc_fork:
+ mk_void(l);
+ break;
+ case sc_rfork:
+ mk_int(l);
+ break;
+ case sc_fauth:
+ mk_int(l);
+ mk_charS(l);
+ break;
+ case sc_fstat:
+ mk_int(l);
+ mk_ucharS(l);
+ mk_int(l);
+ break;
+ case sc_fwstat:
+ mk_int(l);
+ mk_ucharS(l);
+ mk_int(l);
+ break;
+ case sc_fversion:
+ mk_int(l);
+ mk_int(l);
+ mk_charS(l);
+ mk_int(l);
+ break;
+ case sc_mount:
+ mk_int(l);
+ mk_int(l);
+ mk_charS(l);
+ mk_int(l);
+ mk_charS(l);
+ break;
+ case sc_unmount:
+ mk_charS(l);
+ mk_charS(l);
+ break;
+ case sc_noted:
+ mk_int(l);
+ break;
+ case sc_notify:
+
+ // wtf?
+
+ break;
+ case sc_open:
+ mk_charS(l);
+ mk_int(l);
+ break;
+ case sc_fd2path:
+ mk_int(l);
+ mk_charS(l);
+ mk_int(l);
+ break;
+ case sc_pipe:
+ mk_intS(l);
+ break;
+ case sc_pread:
+ mk_int(l);
+ mk_voidS(l);
+ mk_long(l);
+ mk_vlong(l);
+ break;
+ case sc_preadv:
+ mk_int(l);
+ mk_IOchunkS(l);
+ mk_int(l);
+ mk_vlong(l);
+ break;
+ case sc_pwrite:
+ mk_int(l);
+ mk_voidS(l);
+ mk_long(l);
+ mk_vlong(l);
+ break;
+ case sc_pwritev:
+ mk_int(l);
+ mk_IOchunkS(l);
+ mk_int(l);
+ mk_vlong(l);
+ break;
+ case sc_read:
+ mk_int(l);
+ mk_voidS(l);
+ mk_long(l);
+ break;
+ case sc_readn:
+ mk_int(l);
+ mk_voidS(l);
+ mk_long(l);
+ break;
+ case sc_readv:
+ mk_int(l);
+ mk_IOchunkS(l);
+ mk_int(l);
+ break;
+ case sc_remove:
+ mk_charS(l);
+ break;
+ case sc_sbrk:
+ mk_ulong(l);
+ break;
+ case sc_oseek:
+ mk_int(l);
+ mk_long(l);
+ mk_int(l);
+ break;
+ case sc_seek:
+ mk_int(l);
+ mk_vlong(l);
+ mk_int(l);
+ break;
+ case sc_segattach:
+ mk_int(l);
+ mk_charS(l);
+ mk_voidS(l);
+ mk_ulong(l);
+ break;
+ case sc_segbrk:
+ mk_voidS(l);
+ mk_voidS(l);
+ break;
+ case sc_segdetach:
+ mk_voidS(l);
+ break;
+ case sc_segflush:
+ mk_voidS(l);
+ mk_ulong(l);
+ break;
+ case sc_segfree:
+ mk_voidS(l);
+ mk_ulong(l);
+ break;
+ case sc_semacquire:
+ mk_longS(l);
+ mk_int(l);
+ break;
+ case sc_semrelease:
+ mk_longS(l);
+ mk_long(l);
+ break;
+ case sc_sleep:
+ mk_long(l);
+ break;
+ case sc_stat:
+ mk_charS(l);
+ mk_ucharS(l);
+ mk_int(l);
+ break;
+ case sc_tsemacquire:
+ mk_longS(l);
+ mk_ulong(l);
+ break;
+ case sc_wait:
+ mk_void(l);
+ break;
+ case sc_waitpid:
+ mk_void(l);
+ break;
+ case sc_write:
+ mk_int(l);
+ mk_voidS(l);
+ mk_long(l);
+ break;
+ case sc_writev:
+ mk_int(l);
+ mk_IOchunkS(l);
+ mk_int(l);
+ break;
+ case sc_wstat:
+ mk_charS(l);
+ mk_ucharS(l);
+ mk_int(l);
+ break;
+ case sc_rendezvous:
+ mk_voidS(l);
+ mk_voidS(l);
+ break;
+ case sc_dirstat:
+ mk_charS(l);
+ break;
+ case sc_dirfstat:
+ mk_int(l);
+ break;
+ case sc_dirwstat:
+ mk_charS(l);
+ mk_DirS(l);
+ break;
+ case sc_dirfwstat:
+ mk_int(l);
+ mk_DirS(l);
+ break;
+ case sc_dirread:
+ mk_int(l);
+ mk_DirSS(l);
+ break;
+ case sc_nulldir:
+ mk_DirS(l);
+ break;
+ case sc_dirreadall:
+ mk_int(l);
+ mk_DirSS(l);
+ break;
+ case sc_getpid :
+ mk_void(l);
+ break;
+ case sc_getppid:
+ mk_void(l);
+ break;
+ case sc_rerrstr:
+ mk_charS(l);
+ mk_uint(l);
+ break;
+ case sc_sysname:
+ mk_void(l);
+ break;
+ case sc_werrstr:
+ mk_charS(l);
+ break;
+ }
+
+ return nil;
+}
--- /dev/null
+++ b/input.c
@@ -1,0 +1,1199 @@
+#include "fuzz.h"
+
+// Procedurally generate input to syscall
+void
+fuzz(caller *sc)
+{
+ // increment the round counter
+ (sc->round)++;
+
+ debug("DEBUG: sc_c = %d\n", sc->c);
+
+ // TODO
+ switch(sc->c) {
+ case sc_exits : // _exits(char*);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ exits( *(char**)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_abort : // abort(void);
+ dolog("!! Someone called abort, don't do that.\n");
+ /* NOPE
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ abort();
+ */
+
+ break;
+ case sc_access : ; // access(char* : int);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ access( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_alarm : // alarm(ulong);
+ // mutate the input
+ mut_ulong((ulong*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ alarm( *(ulong*)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_await : // await(char* : int);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ await( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_bind : // bind(char* : char* : int);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ *(char**)(((t_type*)lget(&(sc->inputs), 1))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ bind( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_brk : // brk(void*);
+ break;
+ case sc_chdir : // chdir(char*);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ chdir( *(char**)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_close : // close(int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ close(*(int*)((t_type*)lget(&(sc->inputs), 0))->var);
+
+ break;
+ case sc_create : // create(char* : int : ulong);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ // Segfaults when fuzzing close() ↓
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_ulong((ulong*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ create( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(ulong*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_dup : // dup(int : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dup( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var);
+
+ break;
+ case sc_errstr :; // errstr(char* : uint);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_uint((uint*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ //errstr( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ // *(uint*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_exec : // exec(char* : char*[]);
+ //TODO - mut_char_star_arr not implemented
+ /*mut_charstar((char**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ int len = mut_charstararr((char***)((t_type*)lget(&(sc->inputs), 1))->var);
+
+ // compute the hash
+ log_call(sc);
+
+ hjsync();
+
+ exec(*(char**)((t_type*)lget(&(sc->inputs), 0))->var, *(char***)((t_type*)lget(&(sc->inputs), 1))->var);
+
+ free_charstararr((char***)((t_type*)lget(&(sc->inputs), 1))->var, len);
+ */
+ break;
+ case sc_execl : // execl(char* : ...);
+ //TODO - not sure what to do with variable # of parameters
+ fprint(2, "Error: Syscall not implemented!\n");
+ exits("SYSCALL NOT IMPLEMENTED");
+ break;
+ case sc_fork : // fork(void);
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ fork();
+
+ break;
+ case sc_rfork : // rfork(int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ rfork(*(int*)((t_type*)lget(&(sc->inputs), 0))->var);
+
+ break;
+ case sc_fauth : // fauth(int : char*);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ *(char**)(((t_type*)lget(&(sc->inputs), 1))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ fauth( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_fstat : // fstat(int : uchar* : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_ucharstar((unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ fstat( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_fwstat : // fwstat(int : uchar* : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_ucharstar((unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ fwstat( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_fversion : // fversion(int : int : char* : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ *(char**)(((t_type*)lget(&(sc->inputs), 2))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ fversion( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 3))->var );
+
+ break;
+ case sc_mount : // mount(int : int : char* : int : char*);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ *(char**)(((t_type*)lget(&(sc->inputs), 2))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+ *(char**)(((t_type*)lget(&(sc->inputs), 4))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ mount( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 3))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 4))->var );
+
+ break;
+ case sc_unmount : // unmount(char* : char*);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ *(char**)(((t_type*)lget(&(sc->inputs), 1))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ unmount(*(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_noted : // noted(int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ noted(*(int*)((t_type*)lget(&(sc->inputs), 0))->var);
+
+ break;
+ case sc_notify : // notify(void(*)(void* : char*));
+ //TODO - this sc takes a function pointer, we don't have infrastructure for that
+ fprint(2, "Error: Syscall not implemented!\n");
+ exits("SYSCALL NOT IMPLEMENTED");
+ break;
+ case sc_open : // open(char* : int);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ open( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_fd2path : // fd2path(int : char* : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ *(char**)(((t_type*)lget(&(sc->inputs), 1))->var) = mut_charstar();
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ fd2path(*(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_pipe : // pipe(int*);
+ mut_intstar((int**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ log_call(sc);
+
+ hjsync();
+
+ pipe(*(int**)((t_type*)lget(&(sc->inputs), 0))->var);
+
+ break;
+ case sc_pread : // pread(int : void* : long : vlong);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+ mut_vlong((long long*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ pread( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(long long*)((t_type*)lget(&(sc->inputs), 3))->var );
+
+ break;
+ case sc_preadv : // preadv(int : IOchunk* : int : vlong);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_IOchunkstar((IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+ mut_vlong((long long*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ preadv( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(long long*)((t_type*)lget(&(sc->inputs), 3))->var );
+
+ break;
+ case sc_pwrite : // pwrite(int : void* : long : vlong);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+ mut_vlong((long long*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ pwrite( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(long long*)((t_type*)lget(&(sc->inputs), 3))->var );
+
+ break;
+ case sc_pwritev : // pwritev(int : IOchunk* : int : vlong);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_IOchunkstar((IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+ // Segfaults on fuzzing read() ↓
+ mut_vlong((long long*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ pwritev(*(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(long long*)((t_type*)lget(&(sc->inputs), 3))->var );
+
+ break;
+ case sc_read : // read(int : void* : long);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ read( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_readn : // readn(int : void* : long);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ readn( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_readv : // readv(int : IOchunk* : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_IOchunkstar((IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ readv( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_remove : // remove(char*);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ remove( *(char**)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_sbrk : // sbrk(ulong);
+ // mutate the input
+ mut_ulong((ulong*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ sbrk( *(ulong*)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_oseek : // oseek(int : long : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ oseek( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_seek : // seek(int : vlong : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_vlong((long long*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ seek( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(long long*)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_segattach : // segattach(int : char* : void* : ulong);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ *(char**)(((t_type*)lget(&(sc->inputs), 1))->var) = mut_charstar();
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+ mut_ulong((unsigned long*)((t_type*)lget(&(sc->inputs), 3))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ segattach( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 2))->var,
+ *(unsigned long*)((t_type*)lget(&(sc->inputs), 3))->var );
+
+ break;
+ case sc_segbrk : // segbrk(void* : void*);
+ // mutate the input
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ segbrk( *(void**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_segdetach : // segdetach(void*);
+ // mutate the input
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ segdetach( *(void**)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_segflush : // segflush(void* : ulong);
+ // mutate the input
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_ulong((unsigned long*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ segflush( *(void**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(unsigned long*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_segfree : // segfree(void* : ulong);
+ // mutate the input
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_ulong((unsigned long*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ segfree(*(void**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(unsigned long*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_semacquire : // semacquire(long* : int);
+ // mutate the input
+ mut_longstar((long**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ semacquire( *(long**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_semrelease : // semrelease(long* : long);
+ // mutate the input
+ mut_longstar((long**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ semrelease( *(long**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_sleep : // sleep(long);
+ // mutate the input
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ sleep( *(long*)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_stat : // stat(char* : uchar* : int);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_ucharstar((unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ stat( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_tsemacquire : // tsemacquire(long* : ulong);
+ // mutate the input
+ mut_longstar((long**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_ulong((ulong*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ tsemacquire( *(long**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(ulong*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_wait : // wait(void);
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ wait();
+
+ break;
+ case sc_waitpid : // waitpid(void);
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ waitpid();
+
+ break;
+ case sc_write : // write(int : void* : long);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_long((long*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ write( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(long*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_writev : // writev(int : IOchunk* : int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_IOchunkstar((IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ writev( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(IOchunk**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_wstat : // wstat(char* : uchar* : int);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_ucharstar((unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 2))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ wstat( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(unsigned char**)((t_type*)lget(&(sc->inputs), 1))->var,
+ *(int*)((t_type*)lget(&(sc->inputs), 2))->var );
+
+ break;
+ case sc_rendezvous : // rendezvous(void* : void*);
+ // mutate the input
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_voidstar((void**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ rendezvous( *(void**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(void**)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_dirstat : // dirstat(char*);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dirstat( *(char**)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_dirfstat : // dirfstat(int);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dirfstat(*(int*)((t_type*)lget(&(sc->inputs), 0))->var);
+
+ break;
+ case sc_dirwstat : // dirwstat(char* : Dir*);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_dirstar((Dir**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dirwstat( *(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(Dir**)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_dirfwstat : // dirfwstat(int : Dir*);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_dirstar((Dir**)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dirfwstat( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(Dir**)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_dirread : // dirread(int : Dir**);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_dirstar_star((Dir***)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dirread( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(Dir***)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_nulldir : // nulldir(Dir*);
+ // mutate the input
+ mut_dirstar((Dir**)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ nulldir( *(Dir**)((t_type*)lget(&(sc->inputs), 0))->var );
+
+ break;
+ case sc_dirreadall : // dirreadall(int : Dir**);
+ // mutate the input
+ mut_int((int*)((t_type*)lget(&(sc->inputs), 0))->var, &sc->round);
+ mut_dirstar_star((Dir***)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ dirreadall( *(int*)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(Dir***)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_getpid : // getpid(void);
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ getpid();
+
+ break;
+ case sc_getppid : // getppid(void);
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ getppid();
+
+ break;
+ case sc_rerrstr : // rerrstr(char* : uint);
+ // mutate the input
+ *(char**)(((t_type*)lget(&(sc->inputs), 0))->var) = mut_charstar();
+ mut_uint((uint*)((t_type*)lget(&(sc->inputs), 1))->var, &sc->round);
+
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ rerrstr(*(char**)((t_type*)lget(&(sc->inputs), 0))->var,
+ *(uint*)((t_type*)lget(&(sc->inputs), 1))->var );
+
+ break;
+ case sc_sysname : // sysname(void);
+ // log the variables
+ log_call(sc);
+
+ // sync the disk
+ hjsync();
+
+ // execute the call
+ sysname();
+
+ break;
+ case sc_werrstr : // werrstr(char* : ...);
+ //TODO - not sure what to do with variable # of parameters
+ fprint(2, "Error: Syscall not implemented!\n");
+ exits("SYSCALL NOT IMPLEMENTED");
+ break;
+ default:
+ fprint(2, "Error: Unknown system call encountered!\n");
+ exits("Unknown system call");
+
+ }
+}
+
+// Logs the syscall arguments
+void
+log_call(caller *sc)
+{
+ dolog("\nSystem Call: %s\n", sc->name);
+ // legacy since this is printed elsewhere
+ //dolog("\n\tRound #: %d\n", sc->round);
+ dolog("Arguments:\n");
+ int x;
+ for (x = 0; x < (sc->inputs.size); x++) {
+ t_type* ele = lget(&(sc->inputs), x);
+
+ dolog("\t\t%s : ", typenames[ele->t]);
+
+ switch(ele->t) {
+ case t_int :
+ dolog("%d\n", *(int*) ele->var);
+ break;
+ case t_intS :
+ if (sc->round == 0)
+ dolog("NIL");
+ else
+ dolog("%d\n", *(int*) ele->var);
+ break;
+ case t_uint :
+ dolog("%d\n", *(unsigned int*) ele->var);
+ break;
+ case t_long :
+ dolog("%ld\n", *(long*) ele->var);
+ break;
+ case t_ulong :
+ dolog("%lud\n", *(unsigned long*) ele->var);
+ break;
+ case t_vlong :
+ dolog("%lld\n", *(long long*) ele->var);
+ break;
+ case t_longS :
+ if (sc->round == 0)
+ dolog("NIL");
+ else
+ dolog("%ld\n", *(long*) ele->var);
+ break;
+ case t_DirS : //TODO : verify that this works; compiler warns against
+ // It doesn't, Dir* is a pointer to a struct Dir; see libc.h:621
+ // dolog("%s\n", (Dir*) ele->var);
+ break;
+ case t_charS :
+ // TODO -- segfaults
+ debug("ele->var ptr is: %p\n", ele->var);
+ if (ele->var == nil)
+ dolog("Is nil\n");
+ else
+ dolog("%s\n", *(char**) ele->var);
+ break;
+ case t_charSArr :
+ //dolog("%s\n", (char**) ele->var);
+ break;
+ case t_char :
+ dolog("%c\n", *(char*) ele->var);
+ break;
+ case t_uchar :
+ dolog("%c\n", *(unsigned char*) ele->var);
+ break;
+ case t_void:
+ dolog("skipping over…\n");
+ break;
+ default :
+ fprint(2, "Error: Encountered unknown input variable type!\n");
+ exits("Unknown input variable type!");
+ }
+ dolog("\n");
+ }
+}
+
+// Syncs the disk in hjfs
+void
+hjsync()
+{
+ // open file and write to sync disk
+ int hjfs = open("/srv/hjfs.cmd", OWRITE);
+ fprint(hjfs, "sync\n");
+ close(hjfs);
+}
+
+// Init callnames here, is extern in fuzz.h
+char *callnames[NCALLS]= {
+"_exits",
+"abort",
+"access",
+"alarm",
+"await",
+"bind",
+"brk",
+"chdir",
+"close",
+"create",
+"dup",
+"errstr",
+"exec",
+"execl",
+"exits",
+"fork",
+"rfork",
+"fauth",
+"fstat",
+"fwstat",
+"fversion",
+"mount",
+"unmount",
+"noted",
+"notify",
+"open",
+"fd2path",
+"pipe",
+"pread",
+"preadv",
+"pwrite",
+"pwritev",
+"read",
+"readn",
+"readv",
+"remove",
+"sbrk",
+"oseek",
+"seek",
+"segattach",
+"segbrk",
+"segdetach",
+"segflush",
+"segfree",
+"semacquire",
+"semrelease",
+"sleep",
+"stat",
+"tsemacquire",
+"wait",
+"waitpid",
+"write",
+"writev",
+"wstat",
+"rendezvous",
+"dirstat",
+"dirfstat",
+"dirwstat",
+"dirfwstat",
+"dirread",
+"nulldir",
+"dirreadall",
+"getpid",
+"getppid",
+"rerrstr",
+"sysname",
+"werrstr"
+};
+
+// Init callnames here, is extern in fuzz.h
+char *typenames[NTYPES]= {
+"int",
+"int*",
+"uint",
+"IOchunk*",
+"long",
+"long*",
+"ulong",
+"vlong",
+"Dir*",
+"Dir**",
+"char"
+"uchar",
+"uchar*",
+"char*",
+"char*[]",
+"void",
+"void*"
+};
--- /dev/null
+++ b/list.c
@@ -1,0 +1,105 @@
+#include <u.h>
+#include <libc.h>
+#include "list.h"
+
+// Create a new list
+List
+mklist()
+{
+ return (List){nil, 0};
+}
+
+// Append to a list
+void
+ladd(List* l, void* p)
+{
+ int i;
+ Node* new = malloc(sizeof(Node));
+ new->dat = p;
+ new->next = nil;
+ Node* n = l->root;
+
+ if(l->size == 0){
+ l->root = new;
+ new->next = nil;
+ l->size++;
+ return;
+ }
+
+ for(i = 0; i < l->size; i++){
+ if(i != l->size-1)
+ n = n->next;
+ }
+
+ n->next = new;
+ new->next = nil;
+ l->size++;
+ return;
+
+}
+
+// Search → delete from a list
+void*
+ldel(List* l, void* tofind, int(*comp)(void *, void *))
+{
+ int i;
+ void* dat = nil;
+ Node* n = l->root;
+ Node* prev = nil;
+
+ if(l->size == 0){
+ return dat;
+ }
+
+ for(i = 0; i < l->size; i++){
+ if((*comp)(n->dat, tofind)){
+ if(l->size == 1){
+ // 1 node
+ dat = n->dat;
+ free(n);
+ l->root = nil;
+ }else if(i == 0){
+ // 0 nodes
+ l->root = n->next;
+ dat = n->dat;
+ free(n);
+ }else if(i == l->size-1){
+ // We are the last node
+ prev->next = nil;
+ dat = n->dat;
+ free(n);
+ }else{
+ // this is probably unsafe
+ prev->next = n->next;
+ dat = n->dat;
+ free(n);
+ }
+ l->size--;
+ return dat;
+ }
+
+ prev = n;
+ if(i != l->size-1)
+ n = n->next;
+
+ }
+ return dat;
+}
+
+// Gets a list element by "index" -- ArrayList style
+void*
+lget(List *l, int index)
+{
+ // Out of bounds check
+ if(index < 0 || index >= l->size)
+ return nil;
+
+ int i;
+ Node* n = l->root;
+ for(i = 0; i < l->size; i++, n = n->next)
+ if(i == index)
+ return n->dat;
+
+ // Should never happen
+ return nil;
+}
--- /dev/null
+++ b/list.h
@@ -1,0 +1,30 @@
+#ifndef LIST_H
+#define LIST_H
+
+/* List (Queue) Architecture */
+typedef struct Node Node;
+typedef struct List List;
+
+struct Node {
+ Node* next;
+ void* dat;
+};
+
+struct List {
+ Node* root;
+ int size;
+};
+
+// Create a new list
+List mklist(void);
+
+// Append to a list
+void ladd(List*, void*);
+
+// Search → delete from a list
+void* ldel(List*, void*, int(*comp)(void *, void *));
+
+// Access elements of a list by 'index'
+void* lget(List*, int);
+
+#endif
--- /dev/null
+++ b/main.c
@@ -1,0 +1,166 @@
+#include "fuzz.h"
+
+// Global variables are bad
+int logfd = -1; // fd of the log file, initialized in main
+Lock loglck; // Lock for logger
+Lock rnglck; // Lock for rng
+
+// Commandline usage warning
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-n rounds] calls\n", argv0);
+ exits("usage");
+}
+
+// Perform locked logging operation -- wraps print
+void
+dolog(char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ lock(&loglck);
+ vfprint(logfd, fmt, args);
+ unlock(&loglck);
+
+ va_end(args);
+}
+
+// Perform a debug mode print (if built with -DDEBUG)
+void
+debug(char *fmt, ...)
+{
+ #ifdef DEBUG
+ va_list args;
+ va_start(args, fmt);
+
+ vfprint(1, fmt, args);
+
+ va_end(args);
+ #endif
+}
+
+// Thread-safe sleepable random number generator
+int
+rng(void)
+{
+ ulong x;
+ lock(&rnglck);
+ // Generate a number: 0 ≤ x ≤ MAXINT
+ x = nrand(MAXINT);
+ //debug("DEBUG: Generated num is: %d\n", x);
+ unlock(&rnglck);
+ return x;
+}
+
+/* Prototypes */
+void initsctable(void);
+int name2index(char*);
+
+
+// A kernel fuzzer for the Plan 9 kernel
+void
+main(int argc, char *argv[])
+{
+ int nrounds = -1, i;
+ List tofuzz = mklist() ; // List of syscall table ID's to fuzz
+
+ ARGBEGIN{
+ case 'n':
+ // Number of rounds to iterate fuzzing for
+ nrounds = atoi(ARGF());
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ // Initialize the table of all system calls
+ initsctable();
+
+ // If no system calls are specified, throw usage()
+ if(argc == 0)
+ usage();
+
+ // If the call name '?' is specified as the first argument, print all call names
+ if(strcmp(*argv, "?") == 0){
+ int i;
+ for(i = 0; i < NCALLS; i++)
+ print("%s\n", callnames[i]);
+ exits("Listing all known system calls");
+ }
+
+ // Acquire a list of calls specified by spaces (fuzz -n 1 read write seek)
+ for(;*argv;argv++){
+ int index;
+ if((index = name2index(*argv)) > 0){
+
+ debug("DEBUG index %d matched to \"%s\"\n", index, *argv);
+
+ dolog("Loading call: %s\n", *argv);
+ ladd(&tofuzz, &syscalls[index]); // Might be dangerous, pls fix
+ }else{
+ fprint(2, "Error: Invalid system call: %s\n", *argv);
+ exits("Encountered invalid syscall");
+ }
+ }
+
+ logfd = create("./fuzz.log", OWRITE, 0777);
+ if(logfd < 0){
+ fprint(2, "Error: Failed to create/open log file.");
+ exits("log file create fail");
+ }
+
+ int fuzz_seed = truerand();
+ srand(fuzz_seed);
+ dolog("== Seed Value: %d ==\n", fuzz_seed);
+
+ // Operate for the desired number of rounds, -1 is infinite
+ for(i = 0; i < nrounds || nrounds < 0; i++){
+ int j;
+ dolog("== Begin round %d ==\n", i);
+
+ debug("DEBUG: i: %d nrounds: %d\n", i, nrounds);
+
+ for(j = 0; j < tofuzz.size; j++){
+
+ debug("DEBUG: tofuzz.size: %d\n", tofuzz.size);
+
+ caller *fcall = (caller*) lget(&tofuzz, j);
+ dolog(" Fuzzing: %s \n", fcall->name);
+
+ fuzz(fcall); // Fuzz, syncs the disk
+ }
+ }
+
+ fprint(2, "Fuzz ending…\n");
+ close(logfd);
+ exits(nil);
+}
+
+
+// Initialize the syscall table -- hopefully deprecated by a lex/yacc builder
+void
+initsctable(void)
+{
+ int i;
+ for(i = 0; i < NCALLS; i++){
+ syscalls[i].c = (call)i;
+ syscalls[i].name = callnames[i]; // Pointer points to callnames
+ syscalls[i].round = -1;
+ syscalls[i].seed = -1;
+ mkinlist(&(syscalls[i].inputs), (call)i);
+ }
+}
+
+// Given a syscall name, return the index it occurs -- or -1 if not found
+int
+name2index(char* name)
+{
+ int i;
+ for(i = 0; i < NCALLS; i++){
+ if(strcmp(syscalls[i].name, name) == 0)
+ return i;
+ }
+ return -1;
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,22 @@
+</$objtype/mkfile
+
+TARG = fuzz
+
+BIN = /$objtype/bin
+
+OFILES = main.$O \
+ input.$O \
+ mutate.$O \
+ list.$O \
+ inlist.$O
+
+HFILES = fuzz.h list.h mutate.h
+
+MAN = fuzz.man
+
+</sys/src/cmd/mkone
+
+# Add things after this line
+
+debug: nuke
+ mk all 'CFLAGS=$CFLAGS -DDEBUG'
--- /dev/null
+++ b/mutate.c
@@ -1,0 +1,320 @@
+#include "fuzz.h"
+
+#ifndef ROUND_NUM
+#define ROUND_NUM 1
+#endif // ROUND_NUM
+
+void
+mut_int(int* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ *in_val = rng();
+ }
+ else
+ {
+ *in_val = *in_val << (rng() % (4 + 1 - 0) + 0);
+ // Segfaults when fuzzing close() ↓
+ *in_val = *in_val |= (rng() % (15 + 1 - 0) + 0);
+ }
+}
+
+void
+mut_intstar(int** in_val, int* round)
+{
+ if(*round == ROUND_NUM)
+ {
+ in_val = (int**) malloc(sizeof(int*));
+ *in_val = (int*) malloc(sizeof(int));
+ **in_val = rng();
+ }
+ else
+ {
+ **in_val = **in_val << (rng() % (4 + 1 - 0) + 0);
+ **in_val = **in_val |= (rng() % (15 + 1 - 0) + 0);
+ }
+}
+
+void
+mut_uint(unsigned int* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ *in_val = rng();
+ }
+ else
+ {
+ *in_val = *in_val << (rng() % (4 + 1 - 0) + 0);
+ *in_val = *in_val |= (rng() % (15 + 1 - 0) + 0);
+ }
+}
+
+char*
+mut_charstar()
+{
+ int size = (rng() % (256 + 1 - 2) + 2);
+ char* val = calloc(size, sizeof(char));
+ int i;
+ for(i = 0; i < size - 1; i++)
+ {
+ val[i] = rng() % 255;
+ }
+ return val;
+/*
+ // if not round 1, free the previously malloc-ed memory
+ if(in_val != nil)//*round != ROUND_NUM && *round != 0)
+ {
+ // free(*in_val);
+ debug("mut_charstar: in_val != nil\n");
+ }
+ if (*round == 1)
+ {
+ in_val = malloc(1 * sizeof(char*));
+ }
+
+ if(*round > 0){
+ const int MAX_SIZE = 256;
+ int size = rng() % MAX_SIZE + 1;
+
+ debug("inside mut, round: %d in_val: %p\n", *round, in_val);
+
+ *in_val = malloc(sizeof(char) * size);
+ // in_val = malloc(size * sizeof(char));
+
+ int i;
+ for(i = 0; i < size; i++)
+ {
+ (*in_val)[i] = rng() % 255;
+ }
+ (*in_val)[size - 1] = '\0';
+ debug("mut_charstar: *in_val : %s\n", *in_val);
+ debug("mut_charstar: in_val : %p\n", in_val);
+
+ }
+*/
+/* if (*round == 1)
+ {
+ char** c = malloc(1 * sizeof(char*));
+ in_val = c;
+ }
+ if (*round > 0)
+ {
+ const int MAX_SIZE = 256;
+ int size = rng() % MAX_SIZE + 1;
+
+ debug("inside mut, round: %d in_val: %p\n", *round, in_val);
+
+ char** c = (char**) in_val;
+ *c = malloc(size * sizeof(char));
+ debug("inside mut, round %d c: %p in_val: %p\n", *round, c, in_val);
+ int i;
+ for(i = 0; i < size; i++)
+ {
+ (*c)[i] = rng() % 255;
+ }
+ (*c)[size - 1] = '\0';
+
+ }*/
+}
+
+void
+mut_ucharstar(unsigned char** in_val, int *round)
+{
+ // if not round 1, free the previously malloc-ed memory
+ if(*round != ROUND_NUM)
+ free(*in_val);
+
+ const int MAX_SIZE = 2048;
+ int size = rng() % MAX_SIZE + 1;
+
+ *in_val = malloc(sizeof(char) * size);
+
+ int i;
+ for(i = 0; i < size; i++)
+ {
+ (*in_val)[i] = rng() % 255;
+ }
+ (*in_val)[size - 1] = '\0';
+}
+
+int
+mut_charstararr(char*** in_val)
+{
+ int length = (rng() % (16 + 1 - 1) + 1);
+ dolog("Length: %d", length);
+ hjsync();
+ // malloc the pointer to the array
+ in_val = malloc(sizeof(char*));
+ // malloc the pointer to the char arrays
+ *in_val = malloc(length * sizeof(char*));
+
+ int y, z;
+ for (y = 0; y < length; y++)
+ {
+ // malloc the char arrays
+ int size = (rng() % (64 + 1 - 2) + 2);
+ *in_val[y] = calloc(size, sizeof(char));
+ // init the chars to rng values
+ for (z = 0; z < size - 1; z++)
+ {
+ *in_val[y][z] = (rng() % (255 + 1 - 1) + 1);
+ }
+ }
+
+ return length;
+}
+
+void free_charstararr(char*** in_val, int len)
+{
+ int x;
+ for (x = 0; x < len; x++)
+ {
+ free(*in_val[x]);
+ }
+ free(*in_val);
+ free(in_val);
+}
+
+void
+mut_long(long* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ *in_val = (rng() << 16) | rng();
+ }
+ else
+ {
+ *in_val = *in_val << (rng() % (4 + 1 - 0) + 0);
+ *in_val = *in_val |= (rng() % (15 + 1 - 0) + 0);
+ }
+}
+
+void
+mut_longstar(long** in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ // TODO -- check that this is correct
+ in_val = (long**) malloc(sizeof(long*));
+ *in_val = (long*) malloc(sizeof(long));
+ **in_val = (rng() << 16) | rng();
+ }
+ else
+ {
+ **in_val = **in_val << (rng() % (4 + 1 - 0) + 0);
+ // Segfaults when fuzzing sleep ↓
+ **in_val = **in_val |= (rng() % (15 + 1 - 0 ) + 0);
+ }
+}
+
+void
+mut_ulong(unsigned long* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ *in_val = (rng() << 16) | rng();
+ }
+ else
+ {
+ *in_val = *in_val << (rng() % (4 + 1 - 0) + 0);
+ *in_val = *in_val |= (rng() % (15 + 1 - 0) + 0);
+ }
+}
+
+void
+mut_vlong(long long* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ *in_val = (rng() << 48) | (rng() << 32) | (rng() << 16) | rng();
+ }
+ else
+ {
+ *in_val = *in_val << (rng() % (4 + 1 - 0) + 0);
+ *in_val = *in_val |= (rng() % (15 + 1 - 0) + 0);
+ }
+}
+
+void
+mut_void(void* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
+
+void
+mut_voidstar(void** in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
+
+void
+mut_IOchunk(IOchunk* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
+
+void
+mut_IOchunkstar(IOchunk** in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
+
+void
+mut_dir(Dir* in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
+
+void
+mut_dirstar(Dir** in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
+
+void
+mut_dirstar_star(Dir*** in_val, int *round)
+{
+ if(*round == ROUND_NUM)
+ {
+ //*in_val = rng();
+ }
+ else
+ {
+ }
+}
--- /dev/null
+++ b/mutate.h
@@ -1,0 +1,42 @@
+#ifndef MUT_H
+#define MUT_H
+
+void mut_int(int*, int*);
+
+void mut_intstar(int**, int*);
+
+void mut_uint(uint*, int*);
+
+void mut_char(char*, int*);
+
+char* mut_charstar(void);
+
+void mut_ucharstar(unsigned char**, int*);
+
+int mut_charstararr(char***);
+
+void free_charstararr(char***, int);
+
+void mut_long(long*, int*);
+
+void mut_longstar(long**, int*);
+
+void mut_ulong(unsigned long*, int*);
+
+void mut_vlong(long long*, int*);
+
+void mut_void(void*, int*);
+
+void mut_voidstar(void**, int*);
+
+void mut_IOchunk(IOchunk*, int*);
+
+void mut_IOchunkstar(IOchunk**, int*);
+
+void mut_dir(Dir*, int*);
+
+void mut_dirstar(Dir**, int*);
+
+void mut_dirstar_star(Dir***, int*);
+
+#endif