From ab178bf5668bd5bf1a4ca475e1b0edac60da5ebc Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 19 Nov 2016 18:38:25 +0000 Subject: [PATCH] regress: Introduce %_fuzz executables This takes a single input file containing command line arguments, stdin, and syscall stream, and runs the playback on it. This will be useful for fuzzers. Currently nothing calls this. Signed-off-by: Ian Jackson --- .gitignore | 1 + regress/Makefile.in | 11 +++- regress/hfuzz.c | 128 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 regress/hfuzz.c diff --git a/.gitignore b/.gitignore index c0667fc..0d0daf9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ dynamic/libadns.so.* regress/Makefile regress/*_record regress/*_playback +regress/*_fuzz regress/output-*.* regress/pipe.out regress/pipe.err diff --git a/regress/Makefile.in b/regress/Makefile.in index 67f867c..d55c230 100644 --- a/regress/Makefile.in +++ b/regress/Makefile.in @@ -38,9 +38,10 @@ HCPPFLAGS= -DADNS_REGRESS_TEST -I. REDIRLIBOBJS= $(addsuffix _d.o, $(basename $(LIBOBJS))) HARNLOBJS= hcommon.o $(REDIRLIBOBJS) TARGETS= $(addsuffix _record, $(CLIENTS)) \ - $(addsuffix _playback, $(CLIENTS)) + $(addsuffix _playback, $(CLIENTS)) \ + $(addsuffix _fuzz, $(CLIENTS)) ADH_OBJS= adh-main_c.o adh-opts_c.o adh-query_c.o -ALL_OBJS= $(HARNLOBJS) dtest.o hrecord.o hplayback.o hnonfuzz.o +ALL_OBJS= $(HARNLOBJS) dtest.o hrecord.o hplayback.o hnonfuzz.o hfuzz.o .PRECIOUS: $(AUTOCSRCS) $(AUTOCHDRS) @@ -63,6 +64,9 @@ LINK_CMD= $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ %_playback: %_c.o hplayback.o hnonfuzz.o $(HARNLOBJS) $(LINK_CMD) +%_fuzz: %_c.o hplayback.o hfuzz.o $(HARNLOBJS) + $(LINK_CMD) + .SECONDARY: $(addsuffix _c.o, $(filter-out adnshost, $(CLIENTS))) # Without this, make will remove _c.o after building . # This wastes effort. (Debian bug #4073.) @@ -76,6 +80,9 @@ LINK_CMD= $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ adnshost_%: $(ADH_OBJS) h%.o hnonfuzz.o $(HARNLOBJS) $(LINK_CMD) +adnshost_fuzz: $(ADH_OBJS) hplayback.o hfuzz.o $(HARNLOBJS) + $(LINK_CMD) + %_d.o: $(srcdir)/../src/%.c hredirect.h $(CC) $(CFLAGS) $(HCPPFLAGS) -c -g -o $@ $< diff --git a/regress/hfuzz.c b/regress/hfuzz.c new file mode 100644 index 0000000..c260d0d --- /dev/null +++ b/regress/hfuzz.c @@ -0,0 +1,128 @@ +/* nfuzz.c + * (part of complex test harness, not of the library) + * - routines used for fuzzing (a kind of playback) + * + * This file is part of adns, which is + * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson + * Copyright (C) 2014 Mark Wooding + * Copyright (C) 1999-2000,2003,2006 Tony Finch + * Copyright (C) 1991 Massachusetts Institute of Technology + * (See the file INSTALL for full details.) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation. + * + */ +/* + * We read from stdin: + * - command line arguments + * - syscall stream + * - stdin + */ + +#include + +#include "harness.h" + +extern int Hmain(int argc, char **argv); + +FILE *Hfopen(const char *path, const char *mode) { + /* we do not allow adns to open any files */ + errno = EPERM; + return 0; +} + +static int t_argc; +static char **t_argv; + +static FILE *t_stdin; +static int t_sys_fd; + +static int bail(const char *msg) { + fprintf(stderr,"adns fuzz client: %s\n", msg); + exit(-1); +} +static int baile(const char *msg) { + fprintf(stderr,"adns fuzz client: %s: %s\n", msg, strerror(errno)); + exit(-1); +} + +static void chkin(void) { + if (ferror(stdin)) baile("read stdin"); + if (feof(stdin)) bail("eof on stdin"); +} + +static int getint(int max) { + int val; + char c; + chkin(); + int r = scanf("%d%c", &val, &c); + chkin(); + if (r != 2 || c != '\n') bail("bad input format: not integer"); + if (val < 0 || val > max) bail("bad input format: wrong value"); + return val; +} + +static void getnl(void) { + chkin(); + int c = getchar(); + chkin(); + if (c != '\n') bail("bad input format: expected newline"); +} + +int Ttestinputfd(void) { + return t_sys_fd; +} + +void Texit(int rv) { + fprintf(stderr,"**Texit(%d)**\n",rv); + Tallocshutdown(); + exit(0); +} + +int main(int argc, char **argv) { + int i, l; + + if (argc!=1) + bail("usage: *_fuzz (no arguments)"); + + t_argc = getint(50); + t_argv = calloc(t_argc+1, sizeof(*t_argv)); + for (i=0; i0) { + int c = getchar(); + if (c==EOF) break; + fputc(c, t_stdin); + l--; + } + getnl(); + if (ferror(t_stdin) || fflush(t_stdin)) baile("write/flush t_stdin"); + if (fseek(stdin, 0, SEEK_CUR)) baile("seek-flush stdin"); + t_sys_fd = dup(0); if (t_sys_fd < 0) baile("dup stdin"); + if (dup2(fileno(t_stdin), 0)) baile("dup2 t_stdin"); + if (fseek(stdin, 0, SEEK_SET)) baile("rewind t_stdin"); + + if (dup2(1,2)!=2) baile("redirect stderr to stdout"); + + int estatus = Hmain(t_argc, t_argv); + Texit(estatus); +} -- 2.30.2