Mercurial > dropbear
comparison fuzz-wrapfd.c @ 1580:7f2be495dff6 coverity
merge coverity
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 04 Mar 2018 15:07:09 +0800 |
parents | e75dab5bec71 |
children | b579ec254988 |
comparison
equal
deleted
inserted
replaced
1545:0b991dec7ab9 | 1580:7f2be495dff6 |
---|---|
1 #define FUZZ_SKIP_WRAP 1 | |
2 #include "includes.h" | |
3 #include "fuzz-wrapfd.h" | |
4 | |
5 #include "fuzz.h" | |
6 | |
7 #define IOWRAP_MAXFD (FD_SETSIZE-1) | |
8 static const int MAX_RANDOM_IN = 50000; | |
9 static const double CHANCE_CLOSE = 1.0 / 300; | |
10 static const double CHANCE_INTR = 1.0 / 200; | |
11 static const double CHANCE_READ1 = 0.6; | |
12 static const double CHANCE_READ2 = 0.3; | |
13 static const double CHANCE_WRITE1 = 0.8; | |
14 static const double CHANCE_WRITE2 = 0.3; | |
15 | |
16 struct fdwrap { | |
17 enum wrapfd_mode mode; | |
18 buffer *buf; | |
19 int closein; | |
20 int closeout; | |
21 }; | |
22 | |
23 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1]; | |
24 /* for quick selection of in-use descriptors */ | |
25 static int wrap_used[IOWRAP_MAXFD+1]; | |
26 static unsigned int nused; | |
27 static unsigned short rand_state[3]; | |
28 | |
29 void wrapfd_setup(void) { | |
30 TRACE(("wrapfd_setup")) | |
31 nused = 0; | |
32 memset(wrap_fds, 0x0, sizeof(wrap_fds)); | |
33 memset(wrap_used, 0x0, sizeof(wrap_used)); | |
34 | |
35 memset(rand_state, 0x0, sizeof(rand_state)); | |
36 wrapfd_setseed(50); | |
37 } | |
38 | |
39 void wrapfd_setseed(uint32_t seed) { | |
40 memcpy(rand_state, &seed, sizeof(seed)); | |
41 nrand48(rand_state); | |
42 } | |
43 | |
44 void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) { | |
45 TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode)) | |
46 assert(fd >= 0); | |
47 assert(fd <= IOWRAP_MAXFD); | |
48 assert(wrap_fds[fd].mode == UNUSED); | |
49 assert(buf || mode == RANDOMIN); | |
50 | |
51 wrap_fds[fd].mode = mode; | |
52 wrap_fds[fd].buf = buf; | |
53 wrap_fds[fd].closein = 0; | |
54 wrap_fds[fd].closeout = 0; | |
55 wrap_used[nused] = fd; | |
56 | |
57 nused++; | |
58 } | |
59 | |
60 void wrapfd_remove(int fd) { | |
61 unsigned int i, j; | |
62 TRACE(("wrapfd_remove %d", fd)) | |
63 assert(fd >= 0); | |
64 assert(fd <= IOWRAP_MAXFD); | |
65 assert(wrap_fds[fd].mode != UNUSED); | |
66 wrap_fds[fd].mode = UNUSED; | |
67 | |
68 | |
69 /* remove from used list */ | |
70 for (i = 0, j = 0; i < nused; i++) { | |
71 if (wrap_used[i] != fd) { | |
72 wrap_used[j] = wrap_used[i]; | |
73 j++; | |
74 } | |
75 } | |
76 nused--; | |
77 } | |
78 | |
79 int wrapfd_close(int fd) { | |
80 if (fd >= 0 && fd <= IOWRAP_MAXFD && wrap_fds[fd].mode != UNUSED) { | |
81 wrapfd_remove(fd); | |
82 return 0; | |
83 } else { | |
84 return close(fd); | |
85 } | |
86 } | |
87 | |
88 int wrapfd_read(int fd, void *out, size_t count) { | |
89 size_t maxread; | |
90 buffer *buf; | |
91 | |
92 if (!fuzz.wrapfds) { | |
93 return read(fd, out, count); | |
94 } | |
95 | |
96 if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) { | |
97 /* XXX - assertion failure? */ | |
98 TRACE(("Bad read descriptor %d\n", fd)) | |
99 errno = EBADF; | |
100 return -1; | |
101 } | |
102 | |
103 assert(count != 0); | |
104 | |
105 if (wrap_fds[fd].closein || erand48(rand_state) < CHANCE_CLOSE) { | |
106 wrap_fds[fd].closein = 1; | |
107 errno = ECONNRESET; | |
108 return -1; | |
109 } | |
110 | |
111 if (erand48(rand_state) < CHANCE_INTR) { | |
112 errno = EINTR; | |
113 return -1; | |
114 } | |
115 | |
116 buf = wrap_fds[fd].buf; | |
117 if (buf) { | |
118 maxread = MIN(buf->len - buf->pos, count); | |
119 /* returns 0 if buf is EOF, as intended */ | |
120 if (maxread > 0) { | |
121 maxread = nrand48(rand_state) % maxread + 1; | |
122 } | |
123 memcpy(out, buf_getptr(buf, maxread), maxread); | |
124 buf_incrpos(buf, maxread); | |
125 return maxread; | |
126 } | |
127 | |
128 maxread = MIN(MAX_RANDOM_IN, count); | |
129 maxread = nrand48(rand_state) % maxread + 1; | |
130 memset(out, 0xef, maxread); | |
131 return maxread; | |
132 } | |
133 | |
134 int wrapfd_write(int fd, const void* in, size_t count) { | |
135 unsigned const volatile char* volin = in; | |
136 unsigned int i; | |
137 | |
138 if (!fuzz.wrapfds) { | |
139 return write(fd, in, count); | |
140 } | |
141 | |
142 if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) { | |
143 /* XXX - assertion failure? */ | |
144 TRACE(("Bad read descriptor %d\n", fd)) | |
145 errno = EBADF; | |
146 return -1; | |
147 } | |
148 | |
149 assert(count != 0); | |
150 | |
151 /* force read to exercise sanitisers */ | |
152 for (i = 0; i < count; i++) { | |
153 (void)volin[i]; | |
154 } | |
155 | |
156 if (wrap_fds[fd].closeout || erand48(rand_state) < CHANCE_CLOSE) { | |
157 wrap_fds[fd].closeout = 1; | |
158 errno = ECONNRESET; | |
159 return -1; | |
160 } | |
161 | |
162 if (erand48(rand_state) < CHANCE_INTR) { | |
163 errno = EINTR; | |
164 return -1; | |
165 } | |
166 | |
167 return nrand48(rand_state) % (count+1); | |
168 } | |
169 | |
170 int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds, | |
171 fd_set *exceptfds, struct timeval *timeout) { | |
172 int i, nset, sel; | |
173 int ret = 0; | |
174 int fdlist[IOWRAP_MAXFD+1]; | |
175 | |
176 memset(fdlist, 0x0, sizeof(fdlist)); | |
177 | |
178 if (!fuzz.wrapfds) { | |
179 return select(nfds, readfds, writefds, exceptfds, timeout); | |
180 } | |
181 | |
182 assert(nfds <= IOWRAP_MAXFD+1); | |
183 | |
184 if (erand48(rand_state) < CHANCE_INTR) { | |
185 errno = EINTR; | |
186 return -1; | |
187 } | |
188 | |
189 /* read */ | |
190 if (readfds != NULL && erand48(rand_state) < CHANCE_READ1) { | |
191 for (i = 0, nset = 0; i < nfds; i++) { | |
192 if (FD_ISSET(i, readfds)) { | |
193 assert(wrap_fds[i].mode != UNUSED); | |
194 fdlist[nset] = i; | |
195 nset++; | |
196 } | |
197 } | |
198 FD_ZERO(readfds); | |
199 | |
200 if (nset > 0) { | |
201 /* set one */ | |
202 sel = fdlist[nrand48(rand_state) % nset]; | |
203 FD_SET(sel, readfds); | |
204 ret++; | |
205 | |
206 if (erand48(rand_state) < CHANCE_READ2) { | |
207 sel = fdlist[nrand48(rand_state) % nset]; | |
208 if (!FD_ISSET(sel, readfds)) { | |
209 FD_SET(sel, readfds); | |
210 ret++; | |
211 } | |
212 } | |
213 } | |
214 } | |
215 | |
216 /* write */ | |
217 if (writefds != NULL && erand48(rand_state) < CHANCE_WRITE1) { | |
218 for (i = 0, nset = 0; i < nfds; i++) { | |
219 if (FD_ISSET(i, writefds)) { | |
220 assert(wrap_fds[i].mode != UNUSED); | |
221 fdlist[nset] = i; | |
222 nset++; | |
223 } | |
224 } | |
225 FD_ZERO(writefds); | |
226 | |
227 /* set one */ | |
228 if (nset > 0) { | |
229 sel = fdlist[nrand48(rand_state) % nset]; | |
230 FD_SET(sel, writefds); | |
231 ret++; | |
232 | |
233 if (erand48(rand_state) < CHANCE_WRITE2) { | |
234 sel = fdlist[nrand48(rand_state) % nset]; | |
235 if (!FD_ISSET(sel, writefds)) { | |
236 FD_SET(sel, writefds); | |
237 ret++; | |
238 } | |
239 } | |
240 } | |
241 } | |
242 return ret; | |
243 } | |
244 |