comparison fuzz-wrapfd.c @ 1356:3677a510f545 fuzz

add wrapfd. improve fuzzer in makefile
author Matt Johnston <matt@ucc.asn.au>
date Fri, 19 May 2017 00:48:46 +0800
parents
children 08f4fa4dc6a0
comparison
equal deleted inserted replaced
1355:3fdd8c5a0195 1356:3677a510f545
1 #include "includes.h"
2 #include "fuzz-wrapfd.h"
3
4 static const int IOWRAP_MAXFD = FD_SETSIZE-1;
5 static const int MAX_RANDOM_IN = 50000;
6 static const double CHANCE_CLOSE = 1.0 / 300;
7 static const double CHANCE_INTR = 1.0 / 200;
8 static const double CHANCE_READ1 = 0.6;
9 static const double CHANCE_READ2 = 0.3;
10 static const double CHANCE_WRITE1 = 0.8;
11 static const double CHANCE_WRITE2 = 0.3;
12
13 struct fdwrap {
14 enum wrapfd_mode mode;
15 buffer *buf;
16 };
17
18 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1];
19 // for quick selection of in-use descriptors
20 static int wrap_used[IOWRAP_MAXFD+1];
21 static unsigned int nused;
22 static unsigned short rand_state[3];
23
24 void wrapfd_setup(uint32_t seed) {
25 nused = 0;
26 memset(wrap_fds, 0x0, sizeof(wrap_fds));
27
28 *((uint32_t*)rand_state) = seed;
29 nrand48(rand_state);
30 }
31
32 void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) {
33 assert(fd >= 0);
34 assert(fd <= IOWRAP_MAXFD);
35 assert(wrap_fds[fd].mode == UNUSED);
36 assert(buf || mode == RANDOMIN);
37
38 wrap_fds[fd].mode = mode;
39 wrap_fds[fd].buf = buf;
40 wrap_used[nused] = fd;
41
42 nused++;
43 }
44
45 void wrapfd_remove(int fd) {
46 unsigned int i, j;
47 assert(fd >= 0);
48 assert(fd <= IOWRAP_MAXFD);
49 assert(wrap_fds[fd].mode != UNUSED);
50 wrap_fds[fd].mode = UNUSED;
51
52 // remove from used list
53 for (i = 0, j = 0; i < nused; i++) {
54 if (wrap_used[i] != fd) {
55 wrap_used[j] = wrap_used[i];
56 j++;
57 }
58 }
59 nused--;
60 }
61
62
63 int wrapfd_read(int fd, void *out, size_t count) {
64 size_t maxread;
65 buffer *buf;
66
67 if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode != UNUSED) {
68 TRACE(("Bad read descriptor %d\n", fd))
69 errno = EBADF;
70 return -1;
71 }
72
73 assert(count != 0);
74
75 if (erand48(rand_state) < CHANCE_CLOSE) {
76 wrapfd_remove(fd);
77 return 0;
78 }
79
80 if (erand48(rand_state) < CHANCE_INTR) {
81 errno = EINTR;
82 return -1;
83 }
84
85 buf = wrap_fds[fd].buf;
86 if (buf) {
87 maxread = MIN(buf->len - buf->pos, count);
88 // returns 0 if buf is EOF, as intended
89 maxread = nrand48(rand_state) % maxread + 1;
90 memcpy(out, buf_getptr(buf, maxread), maxread);
91 buf_incrpos(buf, maxread);
92 return maxread;
93 }
94
95 maxread = MIN(MAX_RANDOM_IN, count);
96 maxread = nrand48(rand_state) % maxread + 1;
97 memset(out, 0xef, maxread);
98 return maxread;
99 }
100
101 int wrapfd_write(int fd, const void* in, size_t count) {
102 unsigned const volatile char* volin = in;
103 unsigned int i;
104 if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode != UNUSED) {
105 TRACE(("Bad read descriptor %d\n", fd))
106 errno = EBADF;
107 return -1;
108 }
109
110 assert(count != 0);
111
112 // force read to exercise sanitisers
113 for (i = 0; i < count; i++) {
114 (void)volin[i];
115 }
116
117 if (erand48(rand_state) < CHANCE_CLOSE) {
118 wrapfd_remove(fd);
119 return 0;
120 }
121
122 if (erand48(rand_state) < CHANCE_INTR) {
123 errno = EINTR;
124 return -1;
125 }
126
127 return nrand48(rand_state) % (count+1);
128 }
129
130 int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds,
131 fd_set *UNUSED(exceptfds), struct timeval *UNUSED(timeout)) {
132 int i, nset;
133 int ret = 0;
134 int fdlist[IOWRAP_MAXFD+1] = {0};
135
136 assert(nfds <= IOWRAP_MAXFD+1);
137
138 if (erand48(rand_state) < CHANCE_INTR) {
139 errno = EINTR;
140 return -1;
141 }
142
143 // read
144 if (erand48(rand_state) < CHANCE_READ1) {
145 for (i = 0, nset = 0; i < nfds; i++) {
146 if (FD_ISSET(i, readfds)) {
147 assert(wrap_fds[i].mode != UNUSED);
148 fdlist[nset] = i;
149 }
150 }
151 FD_ZERO(readfds);
152
153 if (nset > 0) {
154 // set one
155 FD_SET(fdlist[random() % nset], readfds);
156 ret++;
157
158 if (erand48(rand_state) < CHANCE_READ2) {
159 i = fdlist[random() % nset];
160 if (!FD_ISSET(i, readfds)) {
161 FD_SET(i, readfds);
162 ret++;
163 }
164 }
165 }
166 }
167
168 // write
169 if (erand48(rand_state) < CHANCE_WRITE1) {
170 for (i = 0, nset = 0; i < nfds; i++) {
171 if (FD_ISSET(i, writefds)) {
172 assert(wrap_fds[i].mode != UNUSED);
173 fdlist[nset] = i;
174 }
175 }
176 FD_ZERO(writefds);
177
178 // set one
179 if (nset > 0) {
180 FD_SET(fdlist[nrand48(rand_state) % nset], writefds);
181 ret++;
182
183 if (erand48(rand_state) < CHANCE_WRITE2) {
184 i = fdlist[nrand48(rand_state) % nset];
185 if (!FD_ISSET(i, writefds)) {
186 FD_SET(i, writefds);
187 ret++;
188 }
189 }
190 }
191 }
192 return ret;
193 }