Mercurial > dropbear
comparison fuzz-wrapfd.c @ 1740:dfbe947bdf0d fuzz
Make wrapfd share a common buffer for all FDs
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 15 Oct 2020 22:46:24 +0800 |
parents | 60fceff95858 |
children | 6cf465af5d9f |
comparison
equal
deleted
inserted
replaced
1739:13d834efc376 | 1740:dfbe947bdf0d |
---|---|
5 #include "dbutil.h" | 5 #include "dbutil.h" |
6 | 6 |
7 #include "fuzz.h" | 7 #include "fuzz.h" |
8 | 8 |
9 #define IOWRAP_MAXFD (FD_SETSIZE-1) | 9 #define IOWRAP_MAXFD (FD_SETSIZE-1) |
10 // hopefully above any real fd... | |
11 static const int WRAPFD_STARTFD = 400; | |
10 static const int MAX_RANDOM_IN = 50000; | 12 static const int MAX_RANDOM_IN = 50000; |
11 static const double CHANCE_CLOSE = 1.0 / 600; | 13 static const double CHANCE_CLOSE = 1.0 / 600; |
12 static const double CHANCE_INTR = 1.0 / 900; | 14 static const double CHANCE_INTR = 1.0 / 900; |
13 static const double CHANCE_READ1 = 0.96; | 15 static const double CHANCE_READ1 = 0.96; |
14 static const double CHANCE_READ2 = 0.5; | 16 static const double CHANCE_READ2 = 0.5; |
15 static const double CHANCE_WRITE1 = 0.96; | 17 static const double CHANCE_WRITE1 = 0.96; |
16 static const double CHANCE_WRITE2 = 0.5; | 18 static const double CHANCE_WRITE2 = 0.5; |
17 | 19 |
18 struct fdwrap { | 20 struct fdwrap { |
19 enum wrapfd_mode mode; | 21 enum wrapfd_mode mode; |
20 buffer *buf; | |
21 int closein; | 22 int closein; |
22 int closeout; | 23 int closeout; |
23 }; | 24 }; |
24 | 25 |
25 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1]; | 26 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1]; |
26 /* for quick selection of in-use descriptors */ | |
27 static int wrap_used[IOWRAP_MAXFD+1]; | |
28 static unsigned int nused; | |
29 static unsigned short rand_state[3]; | 27 static unsigned short rand_state[3]; |
30 | 28 static buffer *input_buf; |
31 void wrapfd_setup(void) { | 29 |
30 void wrapfd_setup(buffer *buf) { | |
32 TRACE(("wrapfd_setup")) | 31 TRACE(("wrapfd_setup")) |
33 nused = 0; | |
34 memset(wrap_fds, 0x0, sizeof(wrap_fds)); | 32 memset(wrap_fds, 0x0, sizeof(wrap_fds)); |
35 memset(wrap_used, 0x0, sizeof(wrap_used)); | |
36 | 33 |
37 memset(rand_state, 0x0, sizeof(rand_state)); | 34 memset(rand_state, 0x0, sizeof(rand_state)); |
38 wrapfd_setseed(50); | 35 wrapfd_setseed(50); |
36 input_buf = buf; | |
39 } | 37 } |
40 | 38 |
41 void wrapfd_setseed(uint32_t seed) { | 39 void wrapfd_setseed(uint32_t seed) { |
42 memcpy(rand_state, &seed, sizeof(seed)); | 40 memcpy(rand_state, &seed, sizeof(seed)); |
43 nrand48(rand_state); | 41 nrand48(rand_state); |
44 } | 42 } |
45 | 43 |
46 void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) { | 44 int wrapfd_new() { |
47 TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode)) | 45 int fd; |
48 assert(fd >= 0); | 46 // Find a spare file descriptor to use |
49 assert(fd <= IOWRAP_MAXFD); | 47 for (fd = WRAPFD_STARTFD; fd < IOWRAP_MAXFD; fd++) { |
50 assert(wrap_fds[fd].mode == UNUSED); | 48 if (wrap_fds[fd].mode == UNUSED) { |
51 assert(buf || mode == RANDOMIN); | 49 // check real file descriptors haven't got as far as WRAPFD_STARTFD |
52 | 50 assert(close(fd) == -1 && errno == EBADF); |
53 wrap_fds[fd].mode = mode; | 51 wrap_fds[fd].mode = COMMONBUF; |
54 wrap_fds[fd].buf = buf; | 52 wrap_fds[fd].closein = 0; |
55 wrap_fds[fd].closein = 0; | 53 wrap_fds[fd].closeout = 0; |
56 wrap_fds[fd].closeout = 0; | 54 return fd; |
57 wrap_used[nused] = fd; | 55 } |
58 | 56 } |
59 nused++; | 57 errno = EMFILE; |
58 return -1; | |
60 } | 59 } |
61 | 60 |
62 void wrapfd_remove(int fd) { | 61 void wrapfd_remove(int fd) { |
63 unsigned int i, j; | |
64 TRACE(("wrapfd_remove %d", fd)) | 62 TRACE(("wrapfd_remove %d", fd)) |
65 assert(fd >= 0); | 63 assert(fd >= 0); |
66 assert(fd <= IOWRAP_MAXFD); | 64 assert(fd <= IOWRAP_MAXFD); |
67 assert(wrap_fds[fd].mode != UNUSED); | 65 assert(wrap_fds[fd].mode != UNUSED); |
68 wrap_fds[fd].mode = UNUSED; | 66 wrap_fds[fd].mode = UNUSED; |
69 | |
70 | |
71 /* remove from used list */ | |
72 for (i = 0, j = 0; i < nused; i++) { | |
73 if (wrap_used[i] != fd) { | |
74 wrap_used[j] = wrap_used[i]; | |
75 j++; | |
76 } | |
77 } | |
78 nused--; | |
79 } | 67 } |
80 | 68 |
81 int wrapfd_close(int fd) { | 69 int wrapfd_close(int fd) { |
82 if (fd >= 0 && fd <= IOWRAP_MAXFD && wrap_fds[fd].mode != UNUSED) { | 70 if (fd >= 0 && fd <= IOWRAP_MAXFD && wrap_fds[fd].mode != UNUSED) { |
83 wrapfd_remove(fd); | 71 wrapfd_remove(fd); |
113 if (erand48(rand_state) < CHANCE_INTR) { | 101 if (erand48(rand_state) < CHANCE_INTR) { |
114 errno = EINTR; | 102 errno = EINTR; |
115 return -1; | 103 return -1; |
116 } | 104 } |
117 | 105 |
118 buf = wrap_fds[fd].buf; | 106 if (input_buf) { |
119 if (buf) { | 107 maxread = MIN(input_buf->len - input_buf->pos, count); |
120 maxread = MIN(buf->len - buf->pos, count); | |
121 /* returns 0 if buf is EOF, as intended */ | 108 /* returns 0 if buf is EOF, as intended */ |
122 if (maxread > 0) { | 109 if (maxread > 0) { |
123 maxread = nrand48(rand_state) % maxread + 1; | 110 maxread = nrand48(rand_state) % maxread + 1; |
124 } | 111 } |
125 memcpy(out, buf_getptr(buf, maxread), maxread); | 112 memcpy(out, buf_getptr(input_buf, maxread), maxread); |
126 buf_incrpos(buf, maxread); | 113 buf_incrpos(input_buf, maxread); |
127 return maxread; | 114 return maxread; |
128 } | 115 } |
129 | 116 |
130 maxread = MIN(MAX_RANDOM_IN, count); | 117 maxread = MIN(MAX_RANDOM_IN, count); |
131 maxread = nrand48(rand_state) % maxread + 1; | 118 maxread = nrand48(rand_state) % maxread + 1; |