forked from mkj/dropbear
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add wrapfd. improve fuzzer in makefile
--HG-- branch : fuzz
- Loading branch information
Showing
7 changed files
with
268 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
#include "includes.h" | ||
#include "fuzz-wrapfd.h" | ||
|
||
static const int IOWRAP_MAXFD = FD_SETSIZE-1; | ||
static const int MAX_RANDOM_IN = 50000; | ||
static const double CHANCE_CLOSE = 1.0 / 300; | ||
static const double CHANCE_INTR = 1.0 / 200; | ||
static const double CHANCE_READ1 = 0.6; | ||
static const double CHANCE_READ2 = 0.3; | ||
static const double CHANCE_WRITE1 = 0.8; | ||
static const double CHANCE_WRITE2 = 0.3; | ||
|
||
struct fdwrap { | ||
enum wrapfd_mode mode; | ||
buffer *buf; | ||
}; | ||
|
||
static struct fdwrap wrap_fds[IOWRAP_MAXFD+1]; | ||
// for quick selection of in-use descriptors | ||
static int wrap_used[IOWRAP_MAXFD+1]; | ||
static unsigned int nused; | ||
static unsigned short rand_state[3]; | ||
|
||
void wrapfd_setup(uint32_t seed) { | ||
nused = 0; | ||
memset(wrap_fds, 0x0, sizeof(wrap_fds)); | ||
|
||
*((uint32_t*)rand_state) = seed; | ||
nrand48(rand_state); | ||
} | ||
|
||
void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) { | ||
assert(fd >= 0); | ||
assert(fd <= IOWRAP_MAXFD); | ||
assert(wrap_fds[fd].mode == UNUSED); | ||
assert(buf || mode == RANDOMIN); | ||
|
||
wrap_fds[fd].mode = mode; | ||
wrap_fds[fd].buf = buf; | ||
wrap_used[nused] = fd; | ||
|
||
nused++; | ||
} | ||
|
||
void wrapfd_remove(int fd) { | ||
unsigned int i, j; | ||
assert(fd >= 0); | ||
assert(fd <= IOWRAP_MAXFD); | ||
assert(wrap_fds[fd].mode != UNUSED); | ||
wrap_fds[fd].mode = UNUSED; | ||
|
||
// remove from used list | ||
for (i = 0, j = 0; i < nused; i++) { | ||
if (wrap_used[i] != fd) { | ||
wrap_used[j] = wrap_used[i]; | ||
j++; | ||
} | ||
} | ||
nused--; | ||
} | ||
|
||
|
||
int wrapfd_read(int fd, void *out, size_t count) { | ||
size_t maxread; | ||
buffer *buf; | ||
|
||
if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode != UNUSED) { | ||
TRACE(("Bad read descriptor %d\n", fd)) | ||
errno = EBADF; | ||
return -1; | ||
} | ||
|
||
assert(count != 0); | ||
|
||
if (erand48(rand_state) < CHANCE_CLOSE) { | ||
wrapfd_remove(fd); | ||
return 0; | ||
} | ||
|
||
if (erand48(rand_state) < CHANCE_INTR) { | ||
errno = EINTR; | ||
return -1; | ||
} | ||
|
||
buf = wrap_fds[fd].buf; | ||
if (buf) { | ||
maxread = MIN(buf->len - buf->pos, count); | ||
// returns 0 if buf is EOF, as intended | ||
maxread = nrand48(rand_state) % maxread + 1; | ||
memcpy(out, buf_getptr(buf, maxread), maxread); | ||
buf_incrpos(buf, maxread); | ||
return maxread; | ||
} | ||
|
||
maxread = MIN(MAX_RANDOM_IN, count); | ||
maxread = nrand48(rand_state) % maxread + 1; | ||
memset(out, 0xef, maxread); | ||
return maxread; | ||
} | ||
|
||
int wrapfd_write(int fd, const void* in, size_t count) { | ||
unsigned const volatile char* volin = in; | ||
unsigned int i; | ||
if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode != UNUSED) { | ||
TRACE(("Bad read descriptor %d\n", fd)) | ||
errno = EBADF; | ||
return -1; | ||
} | ||
|
||
assert(count != 0); | ||
|
||
// force read to exercise sanitisers | ||
for (i = 0; i < count; i++) { | ||
(void)volin[i]; | ||
} | ||
|
||
if (erand48(rand_state) < CHANCE_CLOSE) { | ||
wrapfd_remove(fd); | ||
return 0; | ||
} | ||
|
||
if (erand48(rand_state) < CHANCE_INTR) { | ||
errno = EINTR; | ||
return -1; | ||
} | ||
|
||
return nrand48(rand_state) % (count+1); | ||
} | ||
|
||
int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds, | ||
fd_set *UNUSED(exceptfds), struct timeval *UNUSED(timeout)) { | ||
int i, nset; | ||
int ret = 0; | ||
int fdlist[IOWRAP_MAXFD+1] = {0}; | ||
|
||
assert(nfds <= IOWRAP_MAXFD+1); | ||
|
||
if (erand48(rand_state) < CHANCE_INTR) { | ||
errno = EINTR; | ||
return -1; | ||
} | ||
|
||
// read | ||
if (erand48(rand_state) < CHANCE_READ1) { | ||
for (i = 0, nset = 0; i < nfds; i++) { | ||
if (FD_ISSET(i, readfds)) { | ||
assert(wrap_fds[i].mode != UNUSED); | ||
fdlist[nset] = i; | ||
} | ||
} | ||
FD_ZERO(readfds); | ||
|
||
if (nset > 0) { | ||
// set one | ||
FD_SET(fdlist[random() % nset], readfds); | ||
ret++; | ||
|
||
if (erand48(rand_state) < CHANCE_READ2) { | ||
i = fdlist[random() % nset]; | ||
if (!FD_ISSET(i, readfds)) { | ||
FD_SET(i, readfds); | ||
ret++; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// write | ||
if (erand48(rand_state) < CHANCE_WRITE1) { | ||
for (i = 0, nset = 0; i < nfds; i++) { | ||
if (FD_ISSET(i, writefds)) { | ||
assert(wrap_fds[i].mode != UNUSED); | ||
fdlist[nset] = i; | ||
} | ||
} | ||
FD_ZERO(writefds); | ||
|
||
// set one | ||
if (nset > 0) { | ||
FD_SET(fdlist[nrand48(rand_state) % nset], writefds); | ||
ret++; | ||
|
||
if (erand48(rand_state) < CHANCE_WRITE2) { | ||
i = fdlist[nrand48(rand_state) % nset]; | ||
if (!FD_ISSET(i, writefds)) { | ||
FD_SET(i, writefds); | ||
ret++; | ||
} | ||
} | ||
} | ||
} | ||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef FUZZ_WRAPFD_H | ||
#define FUZZ_WRAPFD_H | ||
|
||
#include "buffer.h" | ||
|
||
enum wrapfd_mode { | ||
UNUSED = 0, | ||
PLAIN, | ||
INPROGRESS, | ||
RANDOMIN, | ||
}; | ||
|
||
void wrapfd_setup(uint32_t wrapseed); | ||
// doesn't take ownership of buf. buf is optional. | ||
void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode); | ||
|
||
#endif // FUZZ_WRAPFD_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters