chiark / gitweb /
regress: hfuzzraw work in progress
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 23 Nov 2016 22:50:26 +0000 (22:50 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 11 Jun 2020 15:13:02 +0000 (16:13 +0100)
It compiles. But:
 * close() needs to be handled specially since we are maintaining
   a synthetic fd table
 * it does not work at all yet and probably has other parts missing
 * want to (optionally) generate raw feed as part of playback
 * new fds need to get the chosen fd from the stream (and check
   it for sanity)

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
.gitignore
regress/Makefile.in
regress/hfuzzraw.c.m4 [new file with mode: 0644]

index 81aee7a9162b8787763a39dee2e84ea951735aed..aaf3639454e06079e286b4b693b3d370e24727ff 100644 (file)
@@ -34,6 +34,7 @@ regress/Makefile
 regress/*_record
 regress/*_playback
 regress/*_fuzz
+regress/*_fuzzraw
 regress/output-*.*
 regress/fuzz-*
 regress/pipe.out
@@ -42,6 +43,7 @@ regress/harness.h
 regress/hcommon.c
 regress/hplayback.c
 regress/hrecord.c
+regress/hfuzzraw.c
 regress/hredirect.h
 regress/hsyscalls.h
 src/Makefile
index 5f87f241296283a0ee23f982b4a2ae999a4683b0..36ff10f071e92825e2f5d4637db0202a1038099e 100644 (file)
@@ -27,7 +27,7 @@ PROGS_SYSDEP= @PROGS_HAVE_TSEARCH@
 
 CLIENTS=       adnstest adnshost adnslogres $(PROGS_SYSDEP)
 AUTOCHDRS=     harness.h hsyscalls.h hredirect.h
-AUTOCSRCS=     hrecord.c hplayback.c hcommon.c
+AUTOCSRCS=     hrecord.c hplayback.c hcommon.c hfuzzraw.c
 include                ../settings.make
 include                $(srcdir)/../src/adns.make
 
@@ -39,7 +39,8 @@ REDIRLIBOBJS= $(addsuffix _d.o, $(basename $(LIBOBJS)))
 HARNLOBJS=     hcommon.o $(REDIRLIBOBJS)
 TARGETS=       $(addsuffix _record, $(CLIENTS)) \
                $(addsuffix _playback, $(CLIENTS)) \
-               $(addsuffix _fuzz, $(CLIENTS))
+               $(addsuffix _fuzz, $(CLIENTS)) \
+               $(addsuffix _fuzzraw, $(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 hfuzz.o
 
@@ -84,6 +85,9 @@ LINK_CMD=     $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
 %_fuzz:                %_c.o hplayback.o hfuzz.o $(HARNLOBJS)
                $(LINK_CMD)
 
+%_fuzzraw:     %_c.o hfuzzraw.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.)
@@ -100,6 +104,9 @@ adnshost_%: $(ADH_OBJS) h%.o hnonfuzz.o $(HARNLOBJS)
 adnshost_fuzz: $(ADH_OBJS) hplayback.o hfuzz.o $(HARNLOBJS)
                $(LINK_CMD)
 
+adnshost_fuzzraw: $(ADH_OBJS) hfuzzraw.o hfuzz.o $(HARNLOBJS)
+               $(LINK_CMD)
+
 %_d.o:         $(srcdir)/../src/%.c hredirect.h
                $(CC) $(CFLAGS) $(HCPPFLAGS) -c -g -o $@ $<
 
diff --git a/regress/hfuzzraw.c.m4 b/regress/hfuzzraw.c.m4
new file mode 100644 (file)
index 0000000..c575ddb
--- /dev/null
@@ -0,0 +1,248 @@
+m4_dnl hfuzzraw.c.m4
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - routines for fuzzing
+
+m4_dnl  This file is part of adns, which is
+m4_dnl    Copyright (C) 1997-2000,2003,2006,2014-2016  Ian Jackson
+m4_dnl    Copyright (C) 2014  Mark Wooding
+m4_dnl    Copyright (C) 1999-2000,2003,2006  Tony Finch
+m4_dnl    Copyright (C) 1991 Massachusetts Institute of Technology
+m4_dnl  (See the file INSTALL for full details.)
+m4_dnl  
+m4_dnl  This program is free software; you can redistribute it and/or modify
+m4_dnl  it under the terms of the GNU General Public License as published by
+m4_dnl  the Free Software Foundation; either version 3, or (at your option)
+m4_dnl  any later version.
+m4_dnl  
+m4_dnl  This program is distributed in the hope that it will be useful,
+m4_dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+m4_dnl  GNU General Public License for more details.
+m4_dnl  
+m4_dnl  You should have received a copy of the GNU General Public License
+m4_dnl  along with this program; if not, write to the Free Software Foundation.
+
+m4_include(hmacros.i4)
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+
+
+#include "harness.h"
+
+static vbuf fdtab;
+#define FDF_OPEN     001u
+#define FDF_NONBLOCK 002u
+
+static FILE *Tinputfile;
+
+void Q_vb(void) { abort(); /* we neve called Q_anythig */ }
+
+static void Pformat(const char *what) {
+  fprintf(stderr,"adns test harness: format error in raw log input file: %s\n",what);
+  exit(-1);
+}
+
+extern void Tshutdown(void) {
+}
+
+static void Pcheckinput(void) {
+  if (ferror(Tinputfile)) Tfailed("read test log input file");
+  if (feof(Tinputfile)) Pformat("eof at syscall reply");
+}
+
+void Tensurerecordfile(void) {
+  int fd;
+
+  fd = Ttestinputfd();
+  assert(fd >= 0);
+  Tinputfile= fdopen(fd,"rb");
+    if (!Tinputfile) Tfailed("fdopen record fd");
+
+  while (fdtab.used < 3) {
+    const char fdfstd = FDF_OPEN;
+    if (!adns__vbuf_append(&fdtab,&fdfstd,1)) Tnomem();
+  }
+}
+
+static void P_read(void *p, size_t sz) {
+  ssize_t got = fread(&p,1,sz,Tinputfile);
+  Pcheckinput();
+  assert(got==sz);
+}
+
+#define P_READ(x) (P_read(&(x), sizeof((x))))
+
+static void P_updatetime(void) {
+m4_dnl xxx
+}
+
+static unsigned P_fdf(int fd) {
+  assert(fd>=0 && fd<fdtab.used);
+  return fdtab.buf[fd];
+}
+
+static void Paddr(struct sockaddr *addr, int *lenr) {
+  int l, r;
+  uint16_t port;
+  char buf[512];
+  socklen_t sl = *lenr;
+
+  P_READ(l);
+  if (l<0 || l>=sizeof(buf)-1) Pformat("bad addr len");
+  buf[l]= 0;
+  P_READ(port);
+  r= adns_text2addr(buf,port, adns_qf_addrlit_scope_numeric, addr, &sl);
+  if (r==EINVAL) Pformat("bad addr text");
+  assert(r==ENOSPC);
+  *lenr = sl;
+}
+
+static int Pbytes(byte *buf, int maxlen) {
+  int l;
+  P_READ(l);
+  if (l<0 || l>maxlen) Pformat("bad byte block len");
+  P_read(buf, l);
+  return l;
+}
+
+static void Pfdset(fd_set *set, int max) {
+  uint16_t got;
+  int fd, ngot=0;
+
+  for (fd=0; fd<max; fd++) {
+    if (!FD_ISSET(fd,set)) continue;
+    P_fdf(fd);
+    if (ngot==0) {
+      P_READ(got);
+      ngot= 16;
+    }
+    if (!(got & 1u)) {
+      FD_CLR(fd,set);
+    }
+    got >>= 1;
+    ngot--;
+  }
+}
+
+#ifdef HAVE_POLL
+static void Ppollfds(struct pollfd *fds, int nfds) {
+int fd;
+  for (fd=0; fd<nfds; fd++) {
+    if (!fds[fd].events) continue;
+    P_fdf(fd);
+    P_READ(fds[fd].revents);
+  }
+}
+#endif
+
+m4_define(`hm_syscall', `
+ hm_create_proto_h
+int H$1(hm_args_massage($3,void)) {
+ int r;
+ m4_define(`hm_rv_fd',`')
+ m4_define(`hm_rv_any',`')
+ m4_define(`hm_rv_len',`')
+ m4_define(`hm_rv_must',`')
+ m4_define(`hm_rv_succfail',`')
+ m4_define(`hm_rv_fcntl',`')
+ $2
+
+ hm_create_hqcall_vars
+ $3
+
+ hm_create_hqcall_init($1)
+ $3
+
+ Tensurerecordfile();
+ P_updatetime();
+
+ m4_define(`hm_rv_succfail',`
+  P_READ(r);
+  if (r<0 && -r<Tnerrnos) {
+    errno= Terrnos[-r].v;
+    return -1;
+  } else if (r>0 && r<=255) {
+    errno= r;
+    return -1;
+  } else if (r) {
+    Pformat("wrong errno value");
+  }
+  r= 0;
+ ')
+
+ m4_define(`hm_rv_any',`
+  hm_rv_succfail
+  if (!r) {
+    P_READ(r);
+    if (r<0) Pformat("negative nonerror syscall return");
+  }
+ ')
+ m4_define(`hm_rv_len',`
+  hm_rv_any
+  if (r>($'`1)) Pformat("syscall length return is excessive");
+ ')
+ m4_define(`hm_rv_must',`
+  r= 0;
+ ')
+ m4_define(`hm_rv_fcntl',`
+  unsigned flg = P_fdf(fd);
+  if (cmd == F_GETFL) {
+    r= (flg & FDF_NONBLOCK) ? O_NONBLOCK : 0;
+  } else if (cmd == F_SETFL) {
+    flg &= ~FDF_NONBLOCK;
+    if (arg & O_NONBLOCK)
+      flg |= FDF_NONBLOCK;
+    fdtab.buf[fd]= flg;
+    r= 0;
+  } else {
+    abort();
+  }
+ ')
+ m4_define(`hm_rv_fd',`
+  hm_rv_succfail
+  if (!r) {
+    for (;;) {
+      assert(r < 1000);
+      if (r >= fdtab.used)
+        if (!adns__vbuf_append(&fdtab,"\0",1)) Tnomem();
+      assert(r < fdtab.used);
+      if (!(fdtab.buf[r] & FDF_OPEN)) break;
+      r++;
+    }
+    fdtab.buf[r] |= FDF_OPEN;
+ }
+ ')
+ $2
+
+ hm_create_nothing
+ m4_define(`hm_arg_fdset_io',`Pfdset($'`1,$'`2);')
+ m4_define(`hm_arg_pollfds_io',`Ppollfds($'`1,$'`2);')
+ m4_define(`hm_arg_addr_out',`Paddr($'`1,$'`2);')
+ $3
+
+ hm_create_nothing
+ m4_define(`hm_arg_bytes_out',`r= Pbytes($'`2,$'`4);')
+ $3
+
+ P_updatetime();
+ return r;
+}
+')
+
+m4_define(`hm_specsyscall', `')
+
+m4_include(`hsyscalls.i4')
+