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