Mercurial > dropbear
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 } |