* Implemented signal handling.
* Updated documentation accordingly and improved a few parts.
This commit is contained in:
70
doc/zzuf.1
70
doc/zzuf.1
@@ -4,7 +4,7 @@ zzuf \- multiple purpose fuzzer
|
||||
.SH SYNOPSIS
|
||||
.B zzuf
|
||||
[
|
||||
.B \-vqdhic
|
||||
.B \-cdhiqSv
|
||||
] [
|
||||
.B \-r
|
||||
.I ratio
|
||||
@@ -86,8 +86,8 @@ Do not fuzz files whose name matches the
|
||||
.B <regex>
|
||||
regular expression. This option supersedes anything that is specified by the
|
||||
.B \-\-exclude
|
||||
flag. Use this for instance if you do not know for sure what files your
|
||||
application is going to read, but do not want it to fuzz files in the
|
||||
flag. Use this for instance if you are unsure of what files your
|
||||
application is going to read and do not want it to fuzz files in the
|
||||
.B /etc
|
||||
directory.
|
||||
|
||||
@@ -119,11 +119,14 @@ configuration files at startup and you only want specific files to be fuzzed.
|
||||
Multiple
|
||||
.B \-I
|
||||
flags can be specified, in which case files matching any one of the regular
|
||||
expressions will be fuzzed.
|
||||
expressions will be fuzzed. See also the
|
||||
.B \-c
|
||||
flag.
|
||||
.TP
|
||||
.B \-q, \-\-quiet
|
||||
Hide the output of the fuzzed application. This is useful if the application
|
||||
is very verbose but only its exit code is really useful to you.
|
||||
is very verbose but only its exit code or signaled status is really useful to
|
||||
you.
|
||||
.TP
|
||||
.B \-r, \-\-ratio <ratio>
|
||||
Specify the amount of bits that will be randomly fuzzed. A value of 0
|
||||
@@ -153,6 +156,27 @@ If an interval is specified,
|
||||
will run the application several times, each time with a different seed, and
|
||||
report the behaviour of each run.
|
||||
.TP
|
||||
.B \-S, \-\-signal
|
||||
Prevent children from installing signal handlers for signals that usually
|
||||
cause coredumps. These signals are
|
||||
.BR SIGABRT ,
|
||||
.BR SIGFPE ,
|
||||
.BR SIGILL ,
|
||||
.BR SIGQUIT ,
|
||||
.BR SIGSEGV ,
|
||||
.B SIGTRAP
|
||||
and, if available on the running platform,
|
||||
.BR SIGSYS ,
|
||||
.BR SIGEMT ,
|
||||
.BR SIGBUS ,
|
||||
.B SIGXCPU
|
||||
and
|
||||
.BR SIGXFSZ .
|
||||
Instead of calling the signal handler, the application will simply crash. If
|
||||
you do not want core dumps, you should set appropriate limits with the
|
||||
.B limit coredumpsize
|
||||
command. See your shell's documentation on how to set such limits.
|
||||
.TP
|
||||
.B \-T, \-\-max\-time <n>
|
||||
Automatically terminate child processes that run for more than
|
||||
.B <n>
|
||||
@@ -187,7 +211,7 @@ as the original input and excluding
|
||||
.B .xml
|
||||
files from fuzzing (because
|
||||
.B convert
|
||||
will also open its own configuration files and we do not want
|
||||
will also open its own XML configuration files and we do not want
|
||||
.B zzuf
|
||||
to fuzz them):
|
||||
.nf
|
||||
@@ -215,12 +239,28 @@ to reproduce the same behaviour without using
|
||||
.B % vlc fuzzy-movie.avi
|
||||
|
||||
.fi
|
||||
Fuzz
|
||||
Fuzz 2% of
|
||||
.BR mplayer 's
|
||||
input with seeds 0 to 9999, launching up to 3 simultaneous child processes
|
||||
and killing
|
||||
.BR mplayer
|
||||
if it takes more than one minute to read the file:
|
||||
input bits
|
||||
.RB ( \-r
|
||||
.BR 0.02 )
|
||||
with seeds 0 to 9999
|
||||
.RB ( \-s
|
||||
.BR 0:10000 ),
|
||||
disabling its standard output messages
|
||||
.RB ( \-q ),
|
||||
launching up to three simultaneous child processes
|
||||
.RB ( \-F
|
||||
.BR 3 ),
|
||||
killing
|
||||
.B mplayer
|
||||
if it takes more than one minute to read the file
|
||||
.RB ( \-T
|
||||
.BR 60 )
|
||||
and disabling its
|
||||
.B SIGSEGV
|
||||
signal handler
|
||||
.RB ( \-S ):
|
||||
.fn
|
||||
|
||||
.B % zzuf -c -q -s 0:10000 -F 3 -T 60 -r 0.02 mplayer movie.avi -- -benchmark -vo null -fps 1000
|
||||
@@ -239,6 +279,14 @@ etc. One important unimplemented function is
|
||||
Network fuzzing is not implemented. It is not yet possible to insert or
|
||||
drop bytes from the input, to fuzz according to the file format, or to do
|
||||
all these complicated operations. They are planned, though.
|
||||
|
||||
Due to
|
||||
.B zzuf
|
||||
using
|
||||
.B LD_PRELOAD
|
||||
to run its child processes, it will fail in the presence of any mechanism
|
||||
that disables preloading. For instance setuid root binaries will not be
|
||||
fuzzed.
|
||||
.RI
|
||||
.SH AUTHOR
|
||||
.B Zzuf
|
||||
|
||||
@@ -5,7 +5,8 @@ zzuf_CPPFLAGS = -DLIBDIR=\"$(libdir)/zzuf\"
|
||||
|
||||
pkglib_LTLIBRARIES = libzzuf.la
|
||||
libzzuf_la_SOURCES = libzzuf.c libzzuf.h fuzz.c fuzz.h debug.c debug.h \
|
||||
load-fd.c load-stream.c load.h random.c random.h
|
||||
load-fd.c load-signal.c load-stream.c load.h \
|
||||
random.c random.h
|
||||
libzzuf_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
libzzuf_la_LIBADD = -ldl
|
||||
|
||||
|
||||
@@ -40,8 +40,9 @@
|
||||
/* Global variables */
|
||||
int _zz_ready = 0;
|
||||
int _zz_hasdebug = 0;
|
||||
int _zz_seed = 0;
|
||||
float _zz_ratio = 0.004f;
|
||||
int _zz_seed = 0;
|
||||
int _zz_signal = 0;
|
||||
|
||||
/* Local variables */
|
||||
static regex_t * re_include = NULL;
|
||||
@@ -57,7 +58,7 @@ void _zz_init(void)
|
||||
char *tmp;
|
||||
|
||||
tmp = getenv("ZZUF_DEBUG");
|
||||
if(tmp && *tmp)
|
||||
if(tmp && *tmp == '1')
|
||||
_zz_hasdebug = 1;
|
||||
|
||||
tmp = getenv("ZZUF_SEED");
|
||||
@@ -86,6 +87,10 @@ void _zz_init(void)
|
||||
regcomp(re_exclude, tmp, REG_EXTENDED);
|
||||
}
|
||||
|
||||
tmp = getenv("ZZUF_SIGNAL");
|
||||
if(tmp && *tmp == '1')
|
||||
_zz_signal = 1;
|
||||
|
||||
_zz_fd_init();
|
||||
|
||||
tmp = getenv("ZZUF_STDIN");
|
||||
@@ -93,6 +98,7 @@ void _zz_init(void)
|
||||
_zz_register(0);
|
||||
|
||||
_zz_load_fd();
|
||||
_zz_load_signal();
|
||||
_zz_load_stream();
|
||||
|
||||
_zz_ready = 1;
|
||||
|
||||
@@ -31,8 +31,9 @@ struct fuzz
|
||||
/* Internal variables */
|
||||
extern int _zz_ready;
|
||||
extern int _zz_hasdebug;
|
||||
extern int _zz_seed;
|
||||
extern float _zz_ratio;
|
||||
extern int _zz_seed;
|
||||
extern int _zz_signal;
|
||||
|
||||
/* Library initialisation shit */
|
||||
extern void _zz_init(void) __attribute__((constructor));
|
||||
|
||||
125
src/load-signal.c
Normal file
125
src/load-signal.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This program is free software. It comes without any warranty, to
|
||||
* the extent permitted by applicable law. You can redistribute it
|
||||
* and/or modify it under the terms of the Do What The Fuck You Want
|
||||
* To Public License, Version 2, as published by Sam Hocevar. See
|
||||
* http://sam.zoy.org/wtfpl/COPYING for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* load-signal.c: loaded signal functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* needed for sighandler_t */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#elif defined HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "debug.h"
|
||||
#include "fuzz.h"
|
||||
#include "load.h"
|
||||
|
||||
/* Library functions that we divert */
|
||||
static sighandler_t (*signal_orig) (int signum, sighandler_t handler);
|
||||
static int (*sigaction_orig) (int signum, const struct sigaction *act,
|
||||
struct sigaction *oldact);
|
||||
/* Local functions */
|
||||
static int isfatal(int signum);
|
||||
|
||||
void _zz_load_signal(void)
|
||||
{
|
||||
LOADSYM(signal);
|
||||
LOADSYM(sigaction);
|
||||
}
|
||||
|
||||
static int isfatal(int signum)
|
||||
{
|
||||
switch(signum)
|
||||
{
|
||||
case SIGABRT:
|
||||
case SIGFPE:
|
||||
case SIGILL:
|
||||
case SIGQUIT:
|
||||
case SIGSEGV:
|
||||
case SIGTRAP:
|
||||
#ifdef SIGSYS
|
||||
case SIGSYS:
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
case SIGEMT:
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
case SIGBUS:
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
case SIGXCPU:
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
case SIGXFSZ:
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sighandler_t signal(int signum, sighandler_t handler)
|
||||
{
|
||||
sighandler_t ret;
|
||||
|
||||
if(!_zz_ready)
|
||||
LOADSYM(signal);
|
||||
|
||||
if(!_zz_signal)
|
||||
return signal_orig(signum, handler);
|
||||
|
||||
ret = signal_orig(signum, isfatal(signum) ? SIG_DFL : handler);
|
||||
|
||||
debug("signal(%i, %p) = %p", signum, handler, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(!_zz_ready)
|
||||
LOADSYM(sigaction);
|
||||
|
||||
if(!_zz_signal)
|
||||
return sigaction_orig(signum, act, oldact);
|
||||
|
||||
if(act && isfatal(signum))
|
||||
{
|
||||
struct sigaction newact;
|
||||
memcpy(&newact, act, sizeof(struct sigaction));
|
||||
newact.sa_handler = SIG_DFL;
|
||||
ret = sigaction_orig(signum, &newact, oldact);
|
||||
}
|
||||
else
|
||||
ret = sigaction_orig(signum, act, oldact);
|
||||
|
||||
debug("sigaction(%i, %p, %p) = %i", signum, act, oldact, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
} while(0)
|
||||
|
||||
extern void _zz_load_fd(void);
|
||||
extern void _zz_load_signal(void);
|
||||
extern void _zz_load_stream(void);
|
||||
|
||||
|
||||
28
src/zzuf.c
28
src/zzuf.c
@@ -96,25 +96,26 @@ int main(int argc, char *argv[])
|
||||
static struct option long_options[] =
|
||||
{
|
||||
/* Long option, needs arg, flag, short option */
|
||||
{ "include", 1, NULL, 'I' },
|
||||
{ "exclude", 1, NULL, 'E' },
|
||||
{ "cmdline", 0, NULL, 'c' },
|
||||
{ "stdin", 0, NULL, 'i' },
|
||||
{ "seed", 1, NULL, 's' },
|
||||
{ "ratio", 1, NULL, 'r' },
|
||||
{ "fork", 1, NULL, 'F' },
|
||||
{ "max-bytes", 1, NULL, 'B' },
|
||||
{ "max-time", 1, NULL, 'T' },
|
||||
{ "quiet", 0, NULL, 'q' },
|
||||
{ "cmdline", 0, NULL, 'c' },
|
||||
{ "debug", 0, NULL, 'd' },
|
||||
{ "exclude", 1, NULL, 'E' },
|
||||
{ "fork", 1, NULL, 'F' },
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "stdin", 0, NULL, 'i' },
|
||||
{ "include", 1, NULL, 'I' },
|
||||
{ "quiet", 0, NULL, 'q' },
|
||||
{ "ratio", 1, NULL, 'r' },
|
||||
{ "seed", 1, NULL, 's' },
|
||||
{ "signal", 0, NULL, 'S' },
|
||||
{ "max-time", 1, NULL, 'T' },
|
||||
{ "version", 0, NULL, 'v' },
|
||||
};
|
||||
int c = getopt_long(argc, argv, "B:cdE:F:hiI:qr:s:T:v",
|
||||
int c = getopt_long(argc, argv, "B:cdE:F:hiI:qr:s:ST:v",
|
||||
long_options, &option_index);
|
||||
# else
|
||||
# define MOREINFO "Try `%s -h' for more information.\n"
|
||||
int c = getopt(argc, argv, "B:cdE:F:hiI:qr:s:T:v");
|
||||
int c = getopt(argc, argv, "B:cdE:F:hiI:qr:s:ST:v");
|
||||
# endif
|
||||
if(c == -1)
|
||||
break;
|
||||
@@ -163,6 +164,9 @@ int main(int argc, char *argv[])
|
||||
case 'q': /* --quiet */
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'S': /* --signal */
|
||||
setenv("ZZUF_SIGNAL", "1", 1);
|
||||
break;
|
||||
case 'd': /* --debug */
|
||||
setenv("ZZUF_DEBUG", "1", 1);
|
||||
break;
|
||||
@@ -528,6 +532,7 @@ static void usage(void)
|
||||
printf(" -r, --ratio <ratio> bit fuzzing ratio (default 0.004)\n");
|
||||
printf(" -s, --seed <seed> random seed (default 0)\n");
|
||||
printf(" --seed <start:stop> specify a seed range\n");
|
||||
printf(" -S, --signal prevent children from diverting crashing signals\n");
|
||||
printf(" -T, --max-time <n> kill children that run for more than <n> seconds\n");
|
||||
printf(" -v, --version output version information and exit\n");
|
||||
# else
|
||||
@@ -543,6 +548,7 @@ static void usage(void)
|
||||
printf(" -r <ratio> bit fuzzing ratio (default 0.004)\n");
|
||||
printf(" -s <seed> random seed (default 0)\n");
|
||||
printf(" <start:stop> specify a seed range\n");
|
||||
printf(" -S prevent children from diverting crashing signals\n");
|
||||
printf(" -T <n> kill children that run for more than <n> seconds\n");
|
||||
printf(" -v output version information and exit\n");
|
||||
# endif
|
||||
|
||||
Reference in New Issue
Block a user