* Added auto-increment mode. Not very handy to use yet.
This commit is contained in:
+16
-4
@@ -2,13 +2,13 @@
|
||||
.SH NAME
|
||||
zzuf \- multiple purpose fuzzer
|
||||
.SH SYNOPSIS
|
||||
\fBzzuf\fR [\fB\-cdiMnqSx\fR] [\fB\-r\fR \fIratio\fR] [\fB\-s\fR \fIseed\fR|\fB\-s\fR \fIstart:stop\fR]
|
||||
\fBzzuf\fR [\fB\-AcdiMnqSx\fR] [\fB\-r\fR \fIratio\fR] [\fB\-s\fR \fIseed\fR|\fB\-s\fR \fIstart:stop\fR]
|
||||
.br
|
||||
[\fB\-D\fR \fIdelay\fR] [\fB\-F\fR \fIforks\fR] [\fB\-C\fR \fIcrashes\fR] [\fB\-B\fR \fIbytes\fR]
|
||||
[\fB\-D\fR \fIdelay\fR] [\fB\-F\fR \fIforks\fR] [\fB\-C\fR \fIcrashes\fR] [\fB\-B\fR \fIbytes\fR]
|
||||
.br
|
||||
[\fB\-T\fR \fIseconds\fR] [\fB\-M\fR \fImegabytes\fR] [\fB\-P\fR \fIprotect\fR] [\fB\-R\fR \fIrefuse\fR]
|
||||
[\fB\-T\fR \fIseconds\fR] [\fB\-M\fR \fImegabytes\fR] [\fB\-P\fR \fIprotect\fR] [\fB\-R\fR \fIrefuse\fR]
|
||||
.br
|
||||
[\fB\-I\fR \fIinclude\fR] [\fB\-E\fR \fIexclude\fR] [\fIPROGRAM\fR [\fB\-\-\fR] [\fIARGS\fR]...]
|
||||
[\fB\-I\fR \fIinclude\fR] [\fB\-E\fR \fIexclude\fR] [\fIPROGRAM\fR [\fB\-\-\fR] [\fIARGS\fR]...]
|
||||
.br
|
||||
\fBzzuf \-h\fR | \fB\-\-help\fR
|
||||
.br
|
||||
@@ -38,6 +38,11 @@ if the \fBcat\fR utility had been called:
|
||||
\fB zzuf < /dev/zero\fR
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-A\fR, \fB\-\-autoinc\fR
|
||||
Increment random seed each time a new file is opened. This is only required
|
||||
if the same application is expected to open the same file several times and
|
||||
you want to test a different seed each time.
|
||||
.TP
|
||||
\fB\-B\fR, \fB\-\-max\-bytes\fR=\fIn\fR
|
||||
Automatically terminate child processes that output more than \fIn\fR bytes
|
||||
on the standard output and standard error channels. This is useful to detect
|
||||
@@ -252,6 +257,13 @@ disabling its \fBSIGSEGV\fR signal handler (\fB\-S\fR):
|
||||
.PP
|
||||
\fB zzuf \-c \-r 0.02 \-q \-s 0:10000 \-F 5 \-D 0.5 \-T 60 \-S \\\fR
|
||||
\fB mplayer \-\- \-benchmark \-vo null \-fps 1000 movie.avi\fR
|
||||
.PP
|
||||
Create an HTML-like file that loads 1000 times the same \fBhello.gif\fR image
|
||||
and open it in \fBFirefox\fR in auto-increment mode (\fB\-A\fR):
|
||||
.PP
|
||||
\fB awk \(aqBEGIN { for(i=0; i<1000; i++) { print \\\fR
|
||||
\fB "<img src=\\"hello.gif#"i"\\">" }}\(aq > hello.html\fR
|
||||
\fB zzuf -A -I \(aqhello[.]gif\(aq -r 0.001 firefox hello.html\fR
|
||||
.SH RESTRICTIONS
|
||||
.PP
|
||||
Due to \fBzzuf\fR using shared object preloading (\fBLD_PRELOAD\fR,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <regex.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "libzzuf.h"
|
||||
#include "fd.h"
|
||||
|
||||
@@ -44,7 +45,6 @@ static int has_include = 0, has_exclude = 0;
|
||||
static struct files
|
||||
{
|
||||
int managed;
|
||||
uint64_t seed;
|
||||
uint64_t pos;
|
||||
/* Public stuff */
|
||||
struct fuzz fuzz;
|
||||
@@ -53,6 +53,10 @@ static struct files
|
||||
static int *fds, static_fds[STATIC_FILES];
|
||||
static int maxfd, nfiles;
|
||||
|
||||
static int32_t seed = 0;
|
||||
static float ratio = 0.004f;
|
||||
static int autoinc = 0;
|
||||
|
||||
void _zz_include(char const *regex)
|
||||
{
|
||||
if(regcomp(&re_include, regex, REG_EXTENDED) == 0)
|
||||
@@ -65,6 +69,25 @@ void _zz_exclude(char const *regex)
|
||||
has_exclude = 1;
|
||||
}
|
||||
|
||||
void _zz_setseed(int32_t s)
|
||||
{
|
||||
seed = s;
|
||||
}
|
||||
|
||||
void _zz_setratio(float r)
|
||||
{
|
||||
if(r < 0.0f)
|
||||
r = 0.0f;
|
||||
else if(r > 5.0f)
|
||||
r = 5.0f;
|
||||
ratio = r;
|
||||
}
|
||||
|
||||
void _zz_setautoinc(void)
|
||||
{
|
||||
autoinc = 1;
|
||||
}
|
||||
|
||||
void _zz_fd_init(void)
|
||||
{
|
||||
/* We start with 32 file descriptors. This is to reduce the number of
|
||||
@@ -124,6 +147,11 @@ void _zz_register(int fd)
|
||||
if(fd < 0 || fd > 65535 || (fd < maxfd && fds[fd] != -1))
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if(autoinc)
|
||||
debug("using seed %li", (long int)seed);
|
||||
#endif
|
||||
|
||||
/* If filedescriptor is outside our bounds */
|
||||
while(fd >= maxfd)
|
||||
{
|
||||
@@ -159,11 +187,16 @@ void _zz_register(int fd)
|
||||
|
||||
files[i].managed = 1;
|
||||
files[i].pos = 0;
|
||||
files[i].fuzz.seed = seed;
|
||||
files[i].fuzz.ratio = ratio;
|
||||
files[i].fuzz.cur = -1;
|
||||
#ifdef HAVE_FGETLN
|
||||
files[i].fuzz.tmp = NULL;
|
||||
#endif
|
||||
|
||||
if(autoinc)
|
||||
seed++;
|
||||
|
||||
fds[fd] = i;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
extern void _zz_include(char const *);
|
||||
extern void _zz_exclude(char const *);
|
||||
extern void _zz_setseed(int32_t);
|
||||
extern void _zz_setratio(float);
|
||||
extern void _zz_setautoinc(void);
|
||||
extern void _zz_fd_init(void);
|
||||
extern void _zz_fd_fini(void);
|
||||
|
||||
|
||||
+6
-23
@@ -36,11 +36,10 @@
|
||||
#define MAGIC2 0x783bc31f
|
||||
|
||||
/* Fuzzing variables */
|
||||
static int protect[256];
|
||||
static int refuse[256];
|
||||
static float ratio = 0.004f;
|
||||
static int seed = 0;
|
||||
static int protect[256];
|
||||
static int refuse[256];
|
||||
|
||||
/* Local prototypes */
|
||||
static void readchars(int *, char const *);
|
||||
|
||||
void _zz_protect(char const *list)
|
||||
@@ -53,20 +52,6 @@ void _zz_refuse(char const *list)
|
||||
readchars(refuse, list);
|
||||
}
|
||||
|
||||
void _zz_setseed(int s)
|
||||
{
|
||||
seed = s;
|
||||
}
|
||||
|
||||
void _zz_setratio(float r)
|
||||
{
|
||||
if(r < 0.0f)
|
||||
r = 0.0f;
|
||||
else if(r > 5.0f)
|
||||
r = 5.0f;
|
||||
ratio = r;
|
||||
}
|
||||
|
||||
void _zz_fuzz(int fd, uint8_t *buf, uint64_t len)
|
||||
{
|
||||
uint64_t start, stop;
|
||||
@@ -90,16 +75,14 @@ void _zz_fuzz(int fd, uint8_t *buf, uint64_t len)
|
||||
/* Cache bitmask array */
|
||||
if(fuzz->cur != (int)i)
|
||||
{
|
||||
uint32_t chunkseed = i * MAGIC1;
|
||||
uint32_t chunkseed = (i + (int)(fuzz->ratio * MAGIC1)) ^ MAGIC2;
|
||||
_zz_srand(fuzz->seed ^ chunkseed);
|
||||
|
||||
memset(fuzz->data, 0, CHUNKBYTES);
|
||||
|
||||
/* Add some random dithering to handle ratio < 1.0/CHUNKBYTES */
|
||||
_zz_srand(seed ^ chunkseed);
|
||||
todo = (int)((ratio * (8 * CHUNKBYTES * 1000)
|
||||
todo = (int)((fuzz->ratio * (8 * CHUNKBYTES * 1000)
|
||||
+ _zz_rand(1000)) / 1000.0);
|
||||
_zz_srand(seed ^ chunkseed ^ (todo * MAGIC2));
|
||||
|
||||
while(todo--)
|
||||
{
|
||||
unsigned int idx = _zz_rand(CHUNKBYTES);
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
extern void _zz_protect(char const *);
|
||||
extern void _zz_refuse(char const *);
|
||||
extern void _zz_setseed(int);
|
||||
extern void _zz_setratio(float);
|
||||
|
||||
extern void _zz_fuzz(int, uint8_t *, uint64_t);
|
||||
|
||||
|
||||
@@ -70,6 +70,10 @@ void _zz_init(void)
|
||||
if(tmp && *tmp)
|
||||
_zz_setratio(atof(tmp));
|
||||
|
||||
tmp = getenv("ZZUF_AUTOINC");
|
||||
if(tmp && *tmp == '1')
|
||||
_zz_setautoinc();
|
||||
|
||||
tmp = getenv("ZZUF_PROTECT");
|
||||
if(tmp && *tmp)
|
||||
_zz_protect(tmp);
|
||||
|
||||
+9
-6
@@ -27,6 +27,8 @@
|
||||
|
||||
struct fuzz
|
||||
{
|
||||
uint32_t seed;
|
||||
float ratio;
|
||||
int cur;
|
||||
#ifdef HAVE_FGETLN
|
||||
char *tmp;
|
||||
@@ -35,12 +37,13 @@ struct fuzz
|
||||
};
|
||||
|
||||
/* Internal variables */
|
||||
extern int _zz_ready;
|
||||
extern int _zz_disabled;
|
||||
extern int _zz_hasdebug;
|
||||
extern int _zz_signal;
|
||||
extern int _zz_memory;
|
||||
extern int _zz_network;
|
||||
extern int _zz_ready;
|
||||
extern int _zz_disabled;
|
||||
extern int _zz_hasdebug;
|
||||
extern int _zz_signal;
|
||||
extern int _zz_memory;
|
||||
extern int _zz_network;
|
||||
extern int _zz_autoinc;
|
||||
|
||||
/* Library initialisation shit */
|
||||
extern void _zz_init(void) __attribute__((constructor));
|
||||
|
||||
+11
-5
@@ -111,13 +111,14 @@ int main(int argc, char *argv[])
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
for(;;)
|
||||
{
|
||||
# define OPTSTR "B:cC:dD:E:F:iI:mM:nP:qr:R:s:ST:xhv"
|
||||
# define OPTSTR "AB:cC:dD:E:F:iI:mM:nP:qr:R:s:ST:xhv"
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
# define MOREINFO "Try `%s --help' for more information.\n"
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
/* Long option, needs arg, flag, short option */
|
||||
{ "autoinc", 0, NULL, 'A' },
|
||||
{ "max-bytes", 1, NULL, 'B' },
|
||||
{ "cmdline", 0, NULL, 'c' },
|
||||
{ "max-crashes", 1, NULL, 'C' },
|
||||
@@ -151,6 +152,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 'A': /* --autoinc */
|
||||
setenv("ZZUF_AUTOINC", "1", 1);
|
||||
break;
|
||||
case 'B': /* --max-bytes */
|
||||
maxbytes = atoi(optarg);
|
||||
break;
|
||||
@@ -722,10 +726,10 @@ static void version(void)
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Usage: zzuf [-cdimnqSx] [-r ratio] [-s seed | -s start:stop]\n");
|
||||
printf(" [-D delay] [-F forks] [-C crashes] [-B bytes]\n");
|
||||
printf(" [-T seconds] [-M bytes] [-P protect] [-R refuse]\n");
|
||||
printf(" [-I include] [-E exclude] [PROGRAM [--] [ARGS]...]\n");
|
||||
printf("Usage: zzuf [-AcdimnqSx] [-r ratio] [-s seed | -s start:stop]\n");
|
||||
printf(" [-D delay] [-F forks] [-C crashes] [-B bytes]\n");
|
||||
printf(" [-T seconds] [-M bytes] [-P protect] [-R refuse]\n");
|
||||
printf(" [-I include] [-E exclude] [PROGRAM [--] [ARGS]...]\n");
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
printf(" zzuf -h | --help\n");
|
||||
printf(" zzuf -v | --version\n");
|
||||
@@ -737,6 +741,7 @@ static void usage(void)
|
||||
printf("\n");
|
||||
printf("Mandatory arguments to long options are mandatory for short options too.\n");
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
printf(" -A, --autoinc increment seed each time a new file is opened\n");
|
||||
printf(" -B, --max-bytes <n> kill children that output more than <n> bytes\n");
|
||||
printf(" -c, --cmdline only fuzz files specified in the command line\n");
|
||||
printf(" -C, --max-crashes <n> stop after <n> children have crashed (default 1)\n");
|
||||
@@ -761,6 +766,7 @@ static void usage(void)
|
||||
printf(" -h, --help display this help and exit\n");
|
||||
printf(" -v, --version output version information and exit\n");
|
||||
# else
|
||||
printf(" -A increment seed each time a new file is opened\n");
|
||||
printf(" -B <n> kill children that output more than <n> bytes\n");
|
||||
printf(" -c only fuzz files specified in the command line\n");
|
||||
printf(" -C <n> stop after <n> children have crashed (default 1)\n");
|
||||
|
||||
Reference in New Issue
Block a user