1 /* nfuzz.c
2  * (part of complex test harness, not of the library)
3  * - routines used for fuzzing (a kind of playback)
4  *
5  *  This file is part of adns, which is
6  *    Copyright (C) 1997-2000,2003,2006,2014-2016  Ian Jackson
7  *    Copyright (C) 2014  Mark Wooding
8  *    Copyright (C) 1999-2000,2003,2006  Tony Finch
9  *    Copyright (C) 1991 Massachusetts Institute of Technology
10  *  (See the file INSTALL for full details.)
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 3, or (at your option)
15  *  any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software Foundation.
24  *
25  */
26 /*
27  * We read from stdin:
28  *  - command line arguments
29  *  - syscall stream
30  *  - stdin
31  */
32 
33 #include <stdio.h>
34 
35 #include "harness.h"
36 
37 extern int Hmain(int argc, char **argv);
38 
Hfopen(const char * path,const char * mode)39 FILE *Hfopen(const char *path, const char *mode) {
40   /* we do not allow adns to open any files */
41   errno = EPERM;
42   return 0;
43 }
44 
45 static int t_argc;
46 static char **t_argv;
47 
48 static FILE *t_stdin, *stdoutcopy;
49 static int t_sys_fd;
50 
bail(const char * msg)51 static int bail(const char *msg) {
52   fprintf(stderr,"adns fuzz client: %s\n", msg);
53   exit(-1);
54 }
baile(const char * msg)55 static int baile(const char *msg) {
56   fprintf(stderr,"adns fuzz client: %s: %s\n", msg, strerror(errno));
57   exit(-1);
58 }
59 
chkin(void)60 static void chkin(void) {
61   if (ferror(stdin)) baile("read stdin");
62   if (feof(stdin)) bail("eof on stdin");
63 }
64 
getint(int max)65 static int getint(int max) {
66   int val;
67   char c;
68   chkin();
69   int r = scanf("%d%c", &val, &c);
70   chkin();
71   if (r != 2 || c != '\n') bail("bad input format: not integer");
72   if (val < 0 || val > max) bail("bad input format: wrong value");
73   return val;
74 }
75 
getnl(void)76 static void getnl(void) {
77   chkin();
78   int c = getchar();
79   chkin();
80   if (c != '\n') bail("bad input format: expected newline");
81 }
82 
Ttestinputfd(void)83 int Ttestinputfd(void) {
84   return t_sys_fd;
85 }
86 
Texit(int rv)87 void Texit(int rv) {
88   fprintf(stdoutcopy,"rc=%d\n",rv);
89   if (ferror(stdoutcopy) || fclose(stdoutcopy)) baile("flush rc msg");
90   Tcommonshutdown();
91   exit(0);
92 }
93 
main(int argc,char ** argv)94 int main(int argc, char **argv) {
95   int i, l;
96 
97   if (argc!=1)
98     bail("usage: *_fuzz  (no arguments)");
99 
100   int stdoutcopyfd= dup(1);
101   if (stdoutcopyfd<0) baile("dup 1 again");
102   stdoutcopy= fdopen(stdoutcopyfd,"w");
103   if (!stdoutcopy) baile("fdopen 1 again");
104 
105   t_argc = getint(50);
106   if (!t_argc) bail("too few arguments");
107   t_argv = calloc(t_argc+1, sizeof(*t_argv));
108   for (i=0; i<t_argc; i++) {
109     l = getint(1000);
110     t_argv[i] = calloc(1, l+1);
111     fread(t_argv[i], 1,l, stdin);
112     t_argv[i][l] = 0;
113     getnl();
114   }
115 
116   t_stdin = tmpfile();
117   l = getint(100000);
118   while (l>0) {
119     int c = getchar();
120     if (c==EOF) break;
121     fputc(c, t_stdin);
122     l--;
123   }
124   getnl();
125   if (ferror(t_stdin) || fflush(t_stdin)) baile("write/flush t_stdin");
126   if (fseek(stdin, 0, SEEK_CUR)) baile("seek-flush stdin");
127   t_sys_fd = dup(0);  if (t_sys_fd < 0) baile("dup stdin");
128   if (dup2(fileno(t_stdin), 0)) baile("dup2 t_stdin");
129   if (fseek(stdin, 0, SEEK_SET)) baile("rewind t_stdin");
130 
131   int estatus = Hmain(t_argc, t_argv);
132   Texit(estatus);
133 }
134 
Tmallocshutdown(void)135 void Tmallocshutdown(void) { }
Hmalloc(size_t s)136 void *Hmalloc(size_t s) { assert(s); return malloc(s); }
Hrealloc(void * p,size_t s)137 void *Hrealloc(void *p, size_t s) { assert(s); return realloc(p,s); }
Hfree(void * p)138 void Hfree(void *p) { free(p); }
139