Fix to be able to compile normal(ish) binaries with --enable-fuzz

--HG--
branch : fuzz
This commit is contained in:
Matt Johnston 2018-02-28 22:02:12 +08:00
parent c658b275fd
commit 5f2447edbb
11 changed files with 49 additions and 38 deletions

View File

@ -61,14 +61,22 @@ CONVERTOBJS=dropbearconvert.o keyimport.o
SCPOBJS=scp.o progressmeter.o atomicio.o scpmisc.o compat.o SCPOBJS=scp.o progressmeter.o atomicio.o scpmisc.o compat.o
ifeq (@DROPBEAR_FUZZ@, 1) ifeq (@DROPBEAR_FUZZ@, 1)
COMMONOBJS += fuzz-common.o fuzz-wrapfd.o allobjs = $(COMMONOBJS) fuzz-common.o fuzz-wrapfd.o $(CLISVROBJS) $(CLIOBJS) $(SVROBJS)
endif allobjs:=$(subst svr-main.o, ,$(allobjs))
allobjs:=$(subst cli-main.o, ,$(allobjs))
allobjs:=$(sort $(allobjs))
dropbearobjs=$(allobjs) svr-main.o
dbclientobjs=$(allobjs) cli-main.o
dropbearkeyobjs=$(allobjs) $(KEYOBJS)
dropbearconvertobjs=$(allobjs) $(CONVERTOBJS)
else
dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS) dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS)
dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS) dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS)
dropbearkeyobjs=$(COMMONOBJS) $(KEYOBJS) dropbearkeyobjs=$(COMMONOBJS) $(KEYOBJS)
dropbearconvertobjs=$(COMMONOBJS) $(CONVERTOBJS) dropbearconvertobjs=$(COMMONOBJS) $(CONVERTOBJS)
scpobjs=$(SCPOBJS) scpobjs=$(SCPOBJS)
endif
VPATH=@srcdir@ VPATH=@srcdir@
srcdir=@srcdir@ srcdir=@srcdir@
@ -185,7 +193,7 @@ dbclient: $(HEADERS) $(LIBTOM_DEPS) Makefile
$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS) $(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
dropbearkey dropbearconvert: $(HEADERS) $(LIBTOM_DEPS) Makefile dropbearkey dropbearconvert: $(HEADERS) $(LIBTOM_DEPS) Makefile
$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
# scp doesn't use the libs so is special. # scp doesn't use the libs so is special.
scp: $(SCPOBJS) $(HEADERS) Makefile scp: $(SCPOBJS) $(HEADERS) Makefile
@ -260,7 +268,7 @@ fuzzstandalone: fuzz-harness.o fuzz-targets
svrfuzzobjs=$(subst svr-main.o, ,$(dropbearobjs)) svrfuzzobjs=$(subst svr-main.o, ,$(dropbearobjs))
# build all the fuzzers. This will require fail to link unless built with # build all the fuzzers. This will require fail to link unless built with
# make fuzzers LIBS=-lFuzzer.a # make fuzz-targetsk FUZZLIB=-lFuzzer.a
# or similar - the library provides main(). # or similar - the library provides main().
fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS) fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS)

View File

@ -323,7 +323,7 @@ AC_ARG_ENABLE(shadow,
) )
AC_ARG_ENABLE(fuzz, AC_ARG_ENABLE(fuzz,
[ --enable-fuzz Build fuzzing], [ --enable-fuzz Build fuzzing. Not recommended for deployment.],
[ [
AC_DEFINE(DROPBEAR_FUZZ, 1, Fuzzing) AC_DEFINE(DROPBEAR_FUZZ, 1, Fuzzing)
AC_MSG_NOTICE(Enabling fuzzing) AC_MSG_NOTICE(Enabling fuzzing)

View File

@ -121,7 +121,7 @@ static void generic_dropbear_exit(int exitcode, const char* format,
_dropbear_log(LOG_INFO, fmtbuf, param); _dropbear_log(LOG_INFO, fmtbuf, param);
#if DROPBEAR_FUZZ #if DROPBEAR_FUZZ
// longjmp before cleaning up svr_opts /* longjmp before cleaning up svr_opts */
if (fuzz.do_jmp) { if (fuzz.do_jmp) {
longjmp(fuzz.jmp, 1); longjmp(fuzz.jmp, 1);
} }

View File

@ -154,13 +154,15 @@ int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
return 0; return 0;
} }
// get prefix. input format is /*
// string prefix get prefix. input format is
// uint32 wrapfd seed string prefix
// ... to be extended later uint32 wrapfd seed
// [bytes] ssh input stream ... to be extended later
[bytes] ssh input stream
*/
// be careful to avoid triggering buffer.c assertions /* be careful to avoid triggering buffer.c assertions */
if (fuzz.input->len < 8) { if (fuzz.input->len < 8) {
return 0; return 0;
} }
@ -181,7 +183,7 @@ int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
} else { } else {
m_malloc_free_epoch(1, 1); m_malloc_free_epoch(1, 1);
TRACE(("dropbear_exit longjmped")) TRACE(("dropbear_exit longjmped"))
// dropbear_exit jumped here /* dropbear_exit jumped here */
} }
return 0; return 0;

View File

@ -19,7 +19,7 @@ int main(int argc, char ** argv) {
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') { if (argv[i][0] == '-') {
// ignore arguments /* ignore arguments */
continue; continue;
} }

View File

@ -21,7 +21,7 @@ struct fdwrap {
}; };
static struct fdwrap wrap_fds[IOWRAP_MAXFD+1]; static struct fdwrap wrap_fds[IOWRAP_MAXFD+1];
// for quick selection of in-use descriptors /* for quick selection of in-use descriptors */
static int wrap_used[IOWRAP_MAXFD+1]; static int wrap_used[IOWRAP_MAXFD+1];
static unsigned int nused; static unsigned int nused;
static unsigned short rand_state[3]; static unsigned short rand_state[3];
@ -66,7 +66,7 @@ void wrapfd_remove(int fd) {
wrap_fds[fd].mode = UNUSED; wrap_fds[fd].mode = UNUSED;
// remove from used list /* remove from used list */
for (i = 0, j = 0; i < nused; i++) { for (i = 0, j = 0; i < nused; i++) {
if (wrap_used[i] != fd) { if (wrap_used[i] != fd) {
wrap_used[j] = wrap_used[i]; wrap_used[j] = wrap_used[i];
@ -94,7 +94,7 @@ int wrapfd_read(int fd, void *out, size_t count) {
} }
if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) { if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) {
// XXX - assertion failure? /* XXX - assertion failure? */
TRACE(("Bad read descriptor %d\n", fd)) TRACE(("Bad read descriptor %d\n", fd))
errno = EBADF; errno = EBADF;
return -1; return -1;
@ -116,7 +116,7 @@ int wrapfd_read(int fd, void *out, size_t count) {
buf = wrap_fds[fd].buf; buf = wrap_fds[fd].buf;
if (buf) { if (buf) {
maxread = MIN(buf->len - buf->pos, count); maxread = MIN(buf->len - buf->pos, count);
// returns 0 if buf is EOF, as intended /* returns 0 if buf is EOF, as intended */
if (maxread > 0) { if (maxread > 0) {
maxread = nrand48(rand_state) % maxread + 1; maxread = nrand48(rand_state) % maxread + 1;
} }
@ -140,7 +140,7 @@ int wrapfd_write(int fd, const void* in, size_t count) {
} }
if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) { if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) {
// XXX - assertion failure? /* XXX - assertion failure? */
TRACE(("Bad read descriptor %d\n", fd)) TRACE(("Bad read descriptor %d\n", fd))
errno = EBADF; errno = EBADF;
return -1; return -1;
@ -148,7 +148,7 @@ int wrapfd_write(int fd, const void* in, size_t count) {
assert(count != 0); assert(count != 0);
// force read to exercise sanitisers /* force read to exercise sanitisers */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
(void)volin[i]; (void)volin[i];
} }
@ -186,7 +186,7 @@ int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds,
return -1; return -1;
} }
// read /* read */
if (readfds != NULL && erand48(rand_state) < CHANCE_READ1) { if (readfds != NULL && erand48(rand_state) < CHANCE_READ1) {
for (i = 0, nset = 0; i < nfds; i++) { for (i = 0, nset = 0; i < nfds; i++) {
if (FD_ISSET(i, readfds)) { if (FD_ISSET(i, readfds)) {
@ -198,7 +198,7 @@ int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds,
FD_ZERO(readfds); FD_ZERO(readfds);
if (nset > 0) { if (nset > 0) {
// set one /* set one */
sel = fdlist[nrand48(rand_state) % nset]; sel = fdlist[nrand48(rand_state) % nset];
FD_SET(sel, readfds); FD_SET(sel, readfds);
ret++; ret++;
@ -213,7 +213,7 @@ int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds,
} }
} }
// write /* write */
if (writefds != NULL && erand48(rand_state) < CHANCE_WRITE1) { if (writefds != NULL && erand48(rand_state) < CHANCE_WRITE1) {
for (i = 0, nset = 0; i < nfds; i++) { for (i = 0, nset = 0; i < nfds; i++) {
if (FD_ISSET(i, writefds)) { if (FD_ISSET(i, writefds)) {
@ -224,7 +224,7 @@ int wrapfd_select(int nfds, fd_set *readfds, fd_set *writefds,
} }
FD_ZERO(writefds); FD_ZERO(writefds);
// set one /* set one */
if (nset > 0) { if (nset > 0) {
sel = fdlist[nrand48(rand_state) % nset]; sel = fdlist[nrand48(rand_state) % nset];
FD_SET(sel, writefds); FD_SET(sel, writefds);

1
fuzz.h
View File

@ -2,6 +2,7 @@
#define DROPBEAR_FUZZ_H #define DROPBEAR_FUZZ_H
#include "config.h" #include "config.h"
#if DROPBEAR_FUZZ #if DROPBEAR_FUZZ
#include "includes.h" #include "includes.h"

View File

@ -20,14 +20,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
m_malloc_set_epoch(1); m_malloc_set_epoch(1);
// choose a keytype based on input /* choose a keytype based on input */
uint8_t b = 0; uint8_t b = 0;
size_t i; size_t i;
for (i = 0; i < Size; i++) { for (i = 0; i < Size; i++) {
b ^= Data[i]; b ^= Data[i];
} }
const char* algoname = fuzz_signkey_names[b%DROPBEAR_SIGNKEY_NUM_NAMED]; const char* algoname = fuzz_signkey_names[b%DROPBEAR_SIGNKEY_NUM_NAMED];
const char* keyblob = "blob"; // keep short const char* keyblob = "blob"; /* keep short */
if (setjmp(fuzz.jmp) == 0) { if (setjmp(fuzz.jmp) == 0) {
fuzz_checkpubkey_line(fuzz.input, 5, "/home/me/authorized_keys", fuzz_checkpubkey_line(fuzz.input, 5, "/home/me/authorized_keys",
@ -37,7 +37,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
} else { } else {
m_malloc_free_epoch(1, 1); m_malloc_free_epoch(1, 1);
TRACE(("dropbear_exit longjmped")) TRACE(("dropbear_exit longjmped"))
// dropbear_exit jumped here /* dropbear_exit jumped here */
} }
return 0; return 0;

View File

@ -57,7 +57,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
} else { } else {
m_malloc_free_epoch(1, 1); m_malloc_free_epoch(1, 1);
TRACE(("dropbear_exit longjmped")) TRACE(("dropbear_exit longjmped"))
// dropbear_exit jumped here /* dropbear_exit jumped here */
} }
return 0; return 0;

View File

@ -79,8 +79,8 @@ void write_packet() {
it's likely to be necessary */ it's likely to be necessary */
#if DROPBEAR_FUZZ #if DROPBEAR_FUZZ
if (fuzz.fuzzing) { if (fuzz.fuzzing) {
// pretend to write one packet at a time /* pretend to write one packet at a time */
// TODO(fuzz): randomise amount written based on the fuzz input /* TODO(fuzz): randomise amount written based on the fuzz input */
written = iov[0].iov_len; written = iov[0].iov_len;
} }
else else
@ -368,8 +368,8 @@ static int checkmac() {
#if DROPBEAR_FUZZ #if DROPBEAR_FUZZ
if (fuzz.fuzzing) { if (fuzz.fuzzing) {
// fail 1 in 2000 times to test error path. /* fail 1 in 2000 times to test error path.
// note that mac_bytes is all zero prior to kex, so don't test ==0 ! note that mac_bytes is all zero prior to kex, so don't test ==0 ! */
unsigned int value = *((unsigned int*)&mac_bytes); unsigned int value = *((unsigned int*)&mac_bytes);
if (value % 2000 == 99) { if (value % 2000 == 99) {
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;

View File

@ -186,7 +186,7 @@ void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
} }
#if DROPBEAR_FUZZ #if DROPBEAR_FUZZ
// longjmp before cleaning up svr_opts /* longjmp before cleaning up svr_opts */
if (fuzz.do_jmp) { if (fuzz.do_jmp) {
longjmp(fuzz.jmp, 1); longjmp(fuzz.jmp, 1);
} }