# HG changeset patch # User Matt Johnston # Date 1602773184 -28800 # Node ID dfbe947bdf0db8030bfe880dc557f47bc5211519 # Parent 13d834efc376c4a7ee88f6eb3b80a6e05f7b9573 Make wrapfd share a common buffer for all FDs diff -r 13d834efc376 -r dfbe947bdf0d dbutil.c --- a/dbutil.c Thu Oct 15 19:55:15 2020 +0800 +++ b/dbutil.c Thu Oct 15 22:46:24 2020 +0800 @@ -121,7 +121,6 @@ _dropbear_log(LOG_INFO, fmtbuf, param); #if DROPBEAR_FUZZ - /* longjmp before cleaning up svr_opts */ if (fuzz.do_jmp) { longjmp(fuzz.jmp, 1); } @@ -258,6 +257,12 @@ const int FDIN = 0; const int FDOUT = 1; +#if DROPBEAR_FUZZ + if (fuzz.fuzzing) { + return fuzz_spawn_command(ret_writefd, ret_readfd, ret_errfd, ret_pid); + } +#endif + /* redirect stdin/stdout/stderr */ if (pipe(infds) != 0) { return DROPBEAR_FAILURE; diff -r 13d834efc376 -r dfbe947bdf0d fuzz-common.c --- a/fuzz-common.c Thu Oct 15 19:55:15 2020 +0800 +++ b/fuzz-common.c Thu Oct 15 22:46:24 2020 +0800 @@ -36,7 +36,7 @@ memset(&ses, 0x0, sizeof(ses)); memset(&svr_ses, 0x0, sizeof(svr_ses)); - wrapfd_setup(); + wrapfd_setup(fuzz.input); fuzz_seed(); @@ -78,6 +78,29 @@ load_fixed_hostkeys(); } +#if 0 +void fuzz_cli_setup(void) { + fuzz_common_setup(); + + _dropbear_exit = cli_dropbear_exit; + + char *argv[] = { + "-E", + }; + + int argc = sizeof(argv) / sizeof(*argv); + cli_getopts(argc, argv); + + /* user lookups might be slow, cache it */ + fuzz.pw_name = m_strdup("person"); + fuzz.pw_dir = m_strdup("/tmp"); + fuzz.pw_shell = m_strdup("/bin/zsh"); + fuzz.pw_passwd = m_strdup("!!zzznope"); + + load_fixed_hostkeys(); +} +#endif + static void load_fixed_hostkeys(void) { #include "fuzz-hostkeys.c" @@ -151,6 +174,17 @@ finish_kexhashbuf(); } +/* fake version of spawn_command() */ +int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) { + *ret_writefd = wrapfd_new(); + *ret_readfd = wrapfd_new(); + if (ret_errfd) { + *ret_errfd = wrapfd_new(); + } + ret_pid = 999; + return DROPBEAR_SUCCESS; +} + int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) { static int once = 0; if (!once) { @@ -182,8 +216,7 @@ uint32_t wrapseed = buf_getint(fuzz.input); wrapfd_setseed(wrapseed); - int fakesock = 20; - wrapfd_add(fakesock, fuzz.input, PLAIN); + int fakesock = wrapfd_new(); m_malloc_set_epoch(1); if (setjmp(fuzz.jmp) == 0) { diff -r 13d834efc376 -r dfbe947bdf0d fuzz-harness.c --- a/fuzz-harness.c Thu Oct 15 19:55:15 2020 +0800 +++ b/fuzz-harness.c Thu Oct 15 22:46:24 2020 +0800 @@ -9,7 +9,6 @@ buffer *input = buf_new(100000); for (i = 1; i < argc; i++) { - printf("arg %s\n", argv[i]); #if DEBUG_TRACE if (strcmp(argv[i], "-v") == 0) { debug_trace = 1; diff -r 13d834efc376 -r dfbe947bdf0d fuzz-wrapfd.c --- a/fuzz-wrapfd.c Thu Oct 15 19:55:15 2020 +0800 +++ b/fuzz-wrapfd.c Thu Oct 15 22:46:24 2020 +0800 @@ -7,6 +7,8 @@ #include "fuzz.h" #define IOWRAP_MAXFD (FD_SETSIZE-1) +// hopefully above any real fd... +static const int WRAPFD_STARTFD = 400; static const int MAX_RANDOM_IN = 50000; static const double CHANCE_CLOSE = 1.0 / 600; static const double CHANCE_INTR = 1.0 / 900; @@ -17,25 +19,21 @@ struct fdwrap { enum wrapfd_mode mode; - buffer *buf; int closein; int closeout; }; 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]; +static buffer *input_buf; -void wrapfd_setup(void) { +void wrapfd_setup(buffer *buf) { TRACE(("wrapfd_setup")) - nused = 0; memset(wrap_fds, 0x0, sizeof(wrap_fds)); - memset(wrap_used, 0x0, sizeof(wrap_used)); memset(rand_state, 0x0, sizeof(rand_state)); wrapfd_setseed(50); + input_buf = buf; } void wrapfd_setseed(uint32_t seed) { @@ -43,39 +41,29 @@ nrand48(rand_state); } -void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) { - TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, 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_fds[fd].closein = 0; - wrap_fds[fd].closeout = 0; - wrap_used[nused] = fd; - - nused++; +int wrapfd_new() { + int fd; + // Find a spare file descriptor to use + for (fd = WRAPFD_STARTFD; fd < IOWRAP_MAXFD; fd++) { + if (wrap_fds[fd].mode == UNUSED) { + // check real file descriptors haven't got as far as WRAPFD_STARTFD + assert(close(fd) == -1 && errno == EBADF); + wrap_fds[fd].mode = COMMONBUF; + wrap_fds[fd].closein = 0; + wrap_fds[fd].closeout = 0; + return fd; + } + } + errno = EMFILE; + return -1; } void wrapfd_remove(int fd) { - unsigned int i, j; TRACE(("wrapfd_remove %d", fd)) 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_close(int fd) { @@ -115,15 +103,14 @@ return -1; } - buf = wrap_fds[fd].buf; - if (buf) { - maxread = MIN(buf->len - buf->pos, count); + if (input_buf) { + maxread = MIN(input_buf->len - input_buf->pos, count); /* returns 0 if buf is EOF, as intended */ if (maxread > 0) { maxread = nrand48(rand_state) % maxread + 1; } - memcpy(out, buf_getptr(buf, maxread), maxread); - buf_incrpos(buf, maxread); + memcpy(out, buf_getptr(input_buf, maxread), maxread); + buf_incrpos(input_buf, maxread); return maxread; } diff -r 13d834efc376 -r dfbe947bdf0d fuzz-wrapfd.h --- a/fuzz-wrapfd.h Thu Oct 15 19:55:15 2020 +0800 +++ b/fuzz-wrapfd.h Thu Oct 15 22:46:24 2020 +0800 @@ -5,15 +5,13 @@ enum wrapfd_mode { UNUSED = 0, - PLAIN, - INPROGRESS, - RANDOMIN + COMMONBUF, // using the common buffer }; -void wrapfd_setup(void); +// buf is a common buffer read by all wrapped FDs. doesn't take ownership of buf +void wrapfd_setup(buffer *buf); void wrapfd_setseed(uint32_t seed); -// doesn't take ownership of buf. buf is optional. -void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode); +int wrapfd_new(); // called via #defines for read/write/select int wrapfd_read(int fd, void *out, size_t count); diff -r 13d834efc376 -r dfbe947bdf0d fuzz.h --- a/fuzz.h Thu Oct 15 19:55:15 2020 +0800 +++ b/fuzz.h Thu Oct 15 22:46:24 2020 +0800 @@ -31,6 +31,7 @@ void fuzz_get_socket_address(int fd, char **local_host, char **local_port, char **remote_host, char **remote_port, int host_lookup); void fuzz_fake_send_kexdh_reply(void); +int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid); // fake IO wrappers #ifndef FUZZ_SKIP_WRAP