From 1bd6bb7a23f5e304e0659d727fbf93d469bd5b9a Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 13 Jan 2007 10:50:38 +0000 Subject: [PATCH] * Implemented -D/--delay to avoid fork bombs. --- doc/zzuf.1 | 19 ++++++++++++------- src/zzuf.c | 26 ++++++++++++++++++-------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/doc/zzuf.1 b/doc/zzuf.1 index de8a137..3aa4a37 100644 --- a/doc/zzuf.1 +++ b/doc/zzuf.1 @@ -4,9 +4,9 @@ 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] .br - [\fB\-F\fR \fIforks\fR] [\fB\-C\fR \fIcrashes\fR] [\fB\-B\fR \fIbytes\fR] [\fB\-T\fR \fIseconds\fR] + [\fB\-D\fR \fIdelay\fR] [\fB\-F\fR \fIforks\fR] [\fB\-C\fR \fIcrashes\fR] [\fB\-B\fR \fIbytes\fR] .br - [\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]...] .br @@ -69,6 +69,10 @@ argument. \fB\-d\fR, \fB\-\-debug\fR Activate the display of debug messages. .TP +\fB\-D\fR, \fB\-\-delay\fR=\fIdelay\fR +Do not launch more than one process every \fIdelay\fR seconds. This option +should be used together with \fB\-F\fR to avoid fork bombs. +.TP \fB\-E\fR, \fB\-\-exclude\fR=\fIregex\fR Do not fuzz files whose name matches the \fIregex\fR regular expression. This option supersedes anything that is specified by the \fB\-I\fR flag. Use this @@ -82,7 +86,7 @@ of the regular expressions will be ignored. Specify the number of simultaneous children that can be run. This option is only relevant if the \fB\-s\fR flag is used with an interval -argument. +argument. See also the \fB\-D\fR flag. .TP \fB\-i\fR, \fB\-\-stdin\fR Fuzz the application's standard input. By default \fBzzuf\fR only fuzzes files. @@ -241,11 +245,12 @@ can be read by \fBVLC\fR to reproduce the same behaviour without using .PP Fuzz 2% of \fBMPlayer\fR's input bits (\fB\-r\ 0.02\fR) with seeds 0 to 9999 (\fB\-s\ 0:10000\fR), disabling its standard output messages (\fB\-q\fR), -launching up to three simultaneous child processes (\fB\-F\ 3\fR), killing -\fBMPlayer\fR if it takes more than one minute to read the file (\fB\-T\ 60\fR) -and disabling its \fBSIGSEGV\fR signal handler (\fB\-S\fR): +launching up to five simultaneous child processes (\fB\-F\ 5\fR) but wait at +least half a second between launches (\fB\-D\ 0.5\fR), killing \fBMPlayer\fR +if it takes more than one minute to read the file (\fB\-T\ 60\fR) and +disabling its \fBSIGSEGV\fR signal handler (\fB\-S\fR): .PP -\fB zzuf \-c \-r 0.02 \-q \-s 0:10000 \-F 3 \-T 60 \-S \\\fR +\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 .SH RESTRICTIONS .PP diff --git a/src/zzuf.c b/src/zzuf.c index 8d24f78..3f132be 100644 --- a/src/zzuf.c +++ b/src/zzuf.c @@ -87,6 +87,7 @@ static int md5 = 0; static int checkexit = 0; static int maxmem = -1; static int64_t maxtime = -1; +static int64_t delay = 0; static int64_t lastlaunch = 0; #define ZZUF_FD_SET(fd, p_fdset, maxfd) \ @@ -110,6 +111,7 @@ 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" # ifdef HAVE_GETOPT_LONG # define MOREINFO "Try `%s --help' for more information.\n" int option_index = 0; @@ -120,6 +122,7 @@ int main(int argc, char *argv[]) { "cmdline", 0, NULL, 'c' }, { "max-crashes", 1, NULL, 'C' }, { "debug", 0, NULL, 'd' }, + { "delay", 1, NULL, 'D' }, { "exclude", 1, NULL, 'E' }, { "max-forks", 1, NULL, 'F' }, { "stdin", 0, NULL, 'i' }, @@ -138,11 +141,10 @@ int main(int argc, char *argv[]) { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, }; - int c = getopt_long(argc, argv, "B:cC:dE:F:iI:mM:nP:qr:R:s:ST:xhv", - long_options, &option_index); + int c = getopt_long(argc, argv, OPTSTR, long_options, &option_index); # else # define MOREINFO "Try `%s -h' for more information.\n" - int c = getopt(argc, argv, "B:cC:dE:F:iI:mM:nP:qr:R:s:ST:xhv"); + int c = getopt(argc, argv, OPTSTR); # endif if(c == -1) break; @@ -163,6 +165,9 @@ int main(int argc, char *argv[]) case 'd': /* --debug */ setenv("ZZUF_DEBUG", "1", 1); break; + case 'D': /* --delay */ + delay = (int64_t)(atof(optarg) * 1000000.0); + break; case 'E': /* --exclude */ exclude = merge_regex(exclude, optarg); if(!exclude) @@ -421,6 +426,7 @@ static void spawn_children(void) static int const files[] = { DEBUG_FILENO, STDERR_FILENO, STDOUT_FILENO }; char buf[BUFSIZ]; int fd[3][2]; + int64_t now = _zz_time(); pid_t pid; int i, j; @@ -433,6 +439,9 @@ static void spawn_children(void) if(maxcrashes && crashes >= maxcrashes) return; /* all jobs crashed */ + if(delay > 0 && lastlaunch + delay > now) + return; /* too early */ + /* Find the empty slot */ for(i = 0; i < maxforks; i++) if(child_list[i].status == STATUS_FREE) @@ -483,10 +492,8 @@ static void spawn_children(void) return; } - lastlaunch = _zz_time(); - /* We’re the parent, acknowledge spawn */ - child_list[i].date = lastlaunch; + child_list[i].date = now; child_list[i].pid = pid; for(j = 0; j < 3; j++) { @@ -499,6 +506,7 @@ static void spawn_children(void) if(md5) child_list[i].ctx = _zz_md5_init(); + lastlaunch = now; child_count++; seed++; } @@ -711,8 +719,8 @@ static void version(void) static void usage(void) { printf("Usage: zzuf [-cdimnqSx] [-r ratio] [-s seed | -s start:stop]\n"); - printf(" [-F forks] [-C crashes] [-B bytes] [-T seconds]\n"); - printf(" [-M bytes] [-P protect] [-R refuse]\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"); @@ -729,6 +737,7 @@ static void usage(void) printf(" -c, --cmdline only fuzz files specified in the command line\n"); printf(" -C, --max-crashes stop after children have crashed (default 1)\n"); printf(" -d, --debug print debug messages\n"); + printf(" -D, --delay delay between forks\n"); printf(" -E, --exclude do not fuzz files matching \n"); printf(" -F, --max-forks number of concurrent children (default 1)\n"); printf(" -i, --stdin fuzz standard input\n"); @@ -752,6 +761,7 @@ static void usage(void) printf(" -c only fuzz files specified in the command line\n"); printf(" -C stop after children have crashed (default 1)\n"); printf(" -d print debug messages\n"); + printf(" -D delay between forks\n"); printf(" -E do not fuzz files matching \n"); printf(" -F number of concurrent forks (default 1)\n"); printf(" -i fuzz standard input\n");