From 0363d3c32e08d0c2d5ed0035a1b045259677f319 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 23 May 2017 22:43:34 +0800 Subject: [PATCH] fuzzer-pubkey --HG-- branch : fuzz --- Makefile.in | 5 ++++- dbrandom.c | 2 +- dbrandom.h | 3 --- dbutil.c | 7 +++++++ fuzz-common.c | 4 ++-- fuzz.h | 7 +++++++ fuzzer-pubkey.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ signkey.c | 5 +++++ 8 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 fuzzer-pubkey.c diff --git a/Makefile.in b/Makefile.in index d2f2eeb30..ea41916dc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -245,7 +245,7 @@ default_options.h: default_options.h.in ## Fuzzing targets # list of fuzz targets -FUZZ_TARGETS=fuzzer-preauth +FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey list-fuzz-targets: @echo $(FUZZ_TARGETS) @@ -265,6 +265,9 @@ fuzz-targets: $(FUZZ_TARGETS) fuzzer-preauth: fuzzer-preauth.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) $(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ +fuzzer-pubkey: fuzzer-pubkey.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) + $(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@ + # run this to update hardcoded hostkeys for for fuzzing. # hostkeys.c is checked in to hg. fuzz-hostkeys: diff --git a/dbrandom.c b/dbrandom.c index bb9c4c8e9..3e6e78f2e 100644 --- a/dbrandom.c +++ b/dbrandom.c @@ -182,7 +182,7 @@ static void write_urandom() } #ifdef DROPBEAR_FUZZ -void seedfuzz(void) { +void fuzz_seed(void) { hash_state hs; sha1_init(&hs); sha1_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz")); diff --git a/dbrandom.h b/dbrandom.h index 4ccd62247..6bfb86660 100644 --- a/dbrandom.h +++ b/dbrandom.h @@ -31,8 +31,5 @@ void seedrandom(void); void genrandom(unsigned char* buf, unsigned int len); void addrandom(unsigned char * buf, unsigned int len); void gen_random_mpint(mp_int *max, mp_int *rand); -#ifdef DROPBEAR_FUZZ -void seedfuzz(void); -#endif #endif /* DROPBEAR_RANDOM_H_ */ diff --git a/dbutil.c b/dbutil.c index e7e486a9c..d9bb2dded 100644 --- a/dbutil.c +++ b/dbutil.c @@ -120,6 +120,13 @@ static void generic_dropbear_exit(int exitcode, const char* format, _dropbear_log(LOG_INFO, fmtbuf, param); +#ifdef DROPBEAR_FUZZ + // longjmp before cleaning up svr_opts + if (fuzz.fuzzing) { + longjmp(fuzz.jmp, 1); + } +#endif + exit(exitcode); } diff --git a/fuzz-common.c b/fuzz-common.c index 144bf145a..42f6aab70 100644 --- a/fuzz-common.c +++ b/fuzz-common.c @@ -13,7 +13,7 @@ struct dropbear_fuzz_options fuzz; static void load_fixed_hostkeys(void); -static void common_setup_fuzzer(void) { +void common_setup_fuzzer(void) { fuzz.fuzzing = 1; fuzz.wrapfds = 1; fuzz.input = m_malloc(sizeof(buffer)); @@ -47,7 +47,7 @@ int fuzzer_set_input(const uint8_t *Data, size_t Size) { uint32_t wrapseed = buf_getint(fuzz.input); wrapfd_setup(wrapseed); - seedfuzz(); + fuzz_seed(); return DROPBEAR_SUCCESS; } diff --git a/fuzz.h b/fuzz.h index d0e13b3de..8a5597620 100644 --- a/fuzz.h +++ b/fuzz.h @@ -10,12 +10,19 @@ #include "fuzz-wrapfd.h" // once per process +void common_setup_fuzzer(void); void svr_setup_fuzzer(void); // once per input. returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE int fuzzer_set_input(const uint8_t *Data, size_t Size); +// fuzzer functions that intrude into general code void fuzz_kex_fakealgos(void); +int fuzz_checkpubkey_line(buffer* line, int line_num, char* filename, + const char* algo, unsigned int algolen, + const unsigned char* keyblob, unsigned int keybloblen); +extern const char * const * fuzz_signkey_names; +void fuzz_seed(void); // fake IO wrappers #ifndef FUZZ_SKIP_WRAP diff --git a/fuzzer-pubkey.c b/fuzzer-pubkey.c new file mode 100644 index 000000000..bed0798c9 --- /dev/null +++ b/fuzzer-pubkey.c @@ -0,0 +1,49 @@ +#include "fuzz.h" +#include "session.h" +#include "fuzz-wrapfd.h" +#include "debug.h" + +static void setup_fuzzer(void) { + common_setup_fuzzer(); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + static int once = 0; + if (!once) { + setup_fuzzer(); + once = 1; + } + + m_malloc_set_epoch(1); + + fuzz_seed(); + fuzz.input->data = (unsigned char*)Data; + fuzz.input->len = Size; + fuzz.input->size = Size; + fuzz.input->pos = 0; + + if (Size < 4) { + return 0; + } + + // choose a keytype based on input + uint8_t b = 0; + size_t i; + for (i = 0; i < Size; i++) { + b ^= Data[i]; + } + const char* algoname = fuzz_signkey_names[b%DROPBEAR_SIGNKEY_NUM_NAMED]; + const char* keyblob = "fakekeyblob"; + + if (setjmp(fuzz.jmp) == 0) { + fuzz_checkpubkey_line(fuzz.input, 5, "/home/me/authorized_keys", + algoname, strlen(algoname), + keyblob, strlen(keyblob)); + } else { + m_malloc_free_epoch(1); + TRACE(("dropbear_exit longjmped")) + // dropbear_exit jumped here + } + + return 0; +} diff --git a/signkey.c b/signkey.c index 192ba180d..3d78e350b 100644 --- a/signkey.c +++ b/signkey.c @@ -620,3 +620,8 @@ int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen, return ret; } #endif + +#ifdef DROPBEAR_FUZZ +const char * const * fuzz_signkey_names = signkey_names; + +#endif