chiark / gitweb /
regress: Introduce %_fuzz executables
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 19 Nov 2016 18:38:25 +0000 (18:38 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 11 Jun 2020 15:13:02 +0000 (16:13 +0100)
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 <ijackson@chiark.greenend.org.uk>
.gitignore
regress/Makefile.in
regress/hfuzz.c [new file with mode: 0644]

index c0667fc03f8fd3a49a2c0f5a5adf4e7e01637ee4..0d0daf97674e7dbf04167f32ed141c149705ec04 100644 (file)
@@ -32,6 +32,7 @@ dynamic/libadns.so.*
 regress/Makefile
 regress/*_record
 regress/*_playback
+regress/*_fuzz
 regress/output-*.*
 regress/pipe.out
 regress/pipe.err
index 67f867c3b78e2b5ed6de4fab3d69ab04c989e088..d55c230ff6ed92bd772fbbc0997a912525338d94 100644 (file)
@@ -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 <client>_c.o after building <client>.
 # 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 (file)
index 0000000..c260d0d
--- /dev/null
@@ -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 <stdio.h>
+
+#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; i<t_argc; i++) {
+    l = getint(1000);
+    t_argv[i] = calloc(1, l+1);
+    fread(t_argv[i], 1,l, stdin);
+    t_argv[i][l] = 0;
+    getnl();
+  }
+
+  t_stdin = tmpfile();
+  l = getint(100000);
+  while (l>0) {
+    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);
+}