From 37188de25b804899974d56e0aade0aa8d04253fc Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 16:11:21 -0700 Subject: [PATCH 01/59] entry point --- src/include/deepstate/DeepState.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 8a24179..b466267 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -719,6 +719,10 @@ static int DeepState_RunSavedTestCases(void) { return num_failed_tests; } +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + return 0; // Non-zero return values are reserved for future use. +} + /* Start DeepState and run the tests. Returns the number of failed tests. */ static int DeepState_Run(void) { if (!DeepState_OptionsAreInitialized) { From 5731fbc4e1ef1b9af3cdb0ed0248a2dabaa02d9f Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 16:17:31 -0700 Subject: [PATCH 02/59] fix --- src/include/deepstate/DeepState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index b466267..5020c67 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -719,7 +719,7 @@ static int DeepState_RunSavedTestCases(void) { return num_failed_tests; } -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; // Non-zero return values are reserved for future use. } From e18a26896a06b520c302b2031300cccc91f89855 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 16:46:18 -0700 Subject: [PATCH 03/59] just read the data and run, abort if too large --- src/include/deepstate/DeepState.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 5020c67..aa363f4 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -720,6 +720,35 @@ static int DeepState_RunSavedTestCases(void) { } extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size > sizeof(DeepState_Input)) { + return 0; // Just ignore any too-big inputs + } + + struct DeepState_TestInfo *test = NULL; + + DeepState_Setup(); + +#ifdef LIBFUZZER_WHICH_TEST + for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { + if (strncmp(LIBFUZZER_WHICH_TEST, test->test_name, strlen(FLAGS_input_which_test)) == 0) { + break; + } + } +#else + test = DeepState_FirstTest(); +#endif + + memset((void *) DeepState_Input, 0, sizeof(DeepState_Input)); + DeepState_InputIndex = 0; + + memcpy((void *) DeepState_Input, (void *) Data, Size); + + DeepState_Begin(test); + + enum DeepState_TestRunResult result = DeepState_ForkAndRunTest(test); + + DeepState_Teardown(); + return 0; // Non-zero return values are reserved for future use. } From 68f413b7af88818b4a3f61b566254fe8a2a7ed42 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 16:51:54 -0700 Subject: [PATCH 04/59] fixing link --- src/include/deepstate/DeepState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index aa363f4..29844d3 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -719,7 +719,7 @@ static int DeepState_RunSavedTestCases(void) { return num_failed_tests; } -extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size > sizeof(DeepState_Input)) { return 0; // Just ignore any too-big inputs } From 4ab8a6c7121da131edb0b4d552731b561ac6734b Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 16:54:48 -0700 Subject: [PATCH 05/59] go back to extern --- src/include/deepstate/DeepState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 29844d3..aa363f4 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -719,7 +719,7 @@ static int DeepState_RunSavedTestCases(void) { return num_failed_tests; } -int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size > sizeof(DeepState_Input)) { return 0; // Just ignore any too-big inputs } From 8c02b193711caa0017ac7c6aa3289de5be33a4e2 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 16:58:58 -0700 Subject: [PATCH 06/59] move to .c --- src/include/deepstate/DeepState.h | 33 ------------------------------- src/lib/DeepState.c | 33 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index aa363f4..8a24179 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -719,39 +719,6 @@ static int DeepState_RunSavedTestCases(void) { return num_failed_tests; } -extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size > sizeof(DeepState_Input)) { - return 0; // Just ignore any too-big inputs - } - - struct DeepState_TestInfo *test = NULL; - - DeepState_Setup(); - -#ifdef LIBFUZZER_WHICH_TEST - for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { - if (strncmp(LIBFUZZER_WHICH_TEST, test->test_name, strlen(FLAGS_input_which_test)) == 0) { - break; - } - } -#else - test = DeepState_FirstTest(); -#endif - - memset((void *) DeepState_Input, 0, sizeof(DeepState_Input)); - DeepState_InputIndex = 0; - - memcpy((void *) DeepState_Input, (void *) Data, Size); - - DeepState_Begin(test); - - enum DeepState_TestRunResult result = DeepState_ForkAndRunTest(test); - - DeepState_Teardown(); - - return 0; // Non-zero return values are reserved for future use. -} - /* Start DeepState and run the tests. Returns the number of failed tests. */ static int DeepState_Run(void) { if (!DeepState_OptionsAreInitialized) { diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 112cbda..6e01212 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -544,6 +544,39 @@ bool DeepState_CatchAbandoned(void) { return DeepState_CurrentTestRun->result == DeepState_TestRunAbandon; } +extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size > sizeof(DeepState_Input)) { + return 0; // Just ignore any too-big inputs + } + + struct DeepState_TestInfo *test = NULL; + + DeepState_Setup(); + +#ifdef LIBFUZZER_WHICH_TEST + for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { + if (strncmp(LIBFUZZER_WHICH_TEST, test->test_name, strlen(FLAGS_input_which_test)) == 0) { + break; + } + } +#else + test = DeepState_FirstTest(); +#endif + + memset((void *) DeepState_Input, 0, sizeof(DeepState_Input)); + DeepState_InputIndex = 0; + + memcpy((void *) DeepState_Input, (void *) Data, Size); + + DeepState_Begin(test); + + enum DeepState_TestRunResult result = DeepState_ForkAndRunTest(test); + + DeepState_Teardown(); + + return 0; // Non-zero return values are reserved for future use. +} + /* Overwrite libc's abort. */ void abort(void) { DeepState_Fail(); From 89ceafcea6c6e7a332c9ee93370d7aa26482be12 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 17:10:43 -0700 Subject: [PATCH 07/59] initialize options --- src/lib/DeepState.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 6e01212..c7bfcfd 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -551,6 +551,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { struct DeepState_TestInfo *test = NULL; + DeepState_InitOptions(0, ""); DeepState_Setup(); #ifdef LIBFUZZER_WHICH_TEST From 40661041899b35627587ec95cc6258b5af58c690 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 17:36:57 -0700 Subject: [PATCH 08/59] debugging --- src/lib/DeepState.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index c7bfcfd..79b733f 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -548,7 +548,9 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size > sizeof(DeepState_Input)) { return 0; // Just ignore any too-big inputs } - + + printf("LLVM fuzzing with input of size %u\n", Size); + struct DeepState_TestInfo *test = NULL; DeepState_InitOptions(0, ""); From fe3a4176375e031893c6e9718143b085794e7684 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 21:10:02 -0700 Subject: [PATCH 09/59] special version for libFuzzer that doesn't fork --- src/include/deepstate/DeepState.h | 42 +++++++++++++++++++++++++++++++ src/lib/DeepState.c | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 8a24179..f3bb41b 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -491,6 +491,48 @@ static void DeepState_RunTest(struct DeepState_TestInfo *test) { } } +/* Run a test case, but in libFuzzer, so not inside a fork. */ +static void DeepState_RunTestLLVM(struct DeepState_TestInfo *test) { + /* Run the test. */ + if (!setjmp(DeepState_ReturnToRun)) { + /* Convert uncaught C++ exceptions into a test failure. */ +#if defined(__cplusplus) && defined(__cpp_exceptions) + try { +#endif /* __cplusplus */ + + test->test_func(); /* Run the test function. */ + return(DeepState_TestRunPass); + +#if defined(__cplusplus) && defined(__cpp_exceptions) + } catch(...) { + DeepState_Fail(); + } +#endif /* __cplusplus */ + + /* We caught a failure when running the test. */ + } else if (DeepState_CatchFail()) { + DeepState_LogFormat(DeepState_LogError, "Failed: %s", test->test_name); + if (HAS_FLAG_output_test_dir) { + DeepState_SaveFailingTest(); + } + return(DeepState_TestRunFail); + + /* The test was abandoned. We may have gotten soft failures before + * abandoning, so we prefer to catch those first. */ + } else if (DeepState_CatchAbandoned()) { + DeepState_LogFormat(DeepState_LogError, "Abandoned: %s", test->test_name); + return(DeepState_TestRunAbandon); + + /* The test passed. */ + } else { + DeepState_LogFormat(DeepState_LogInfo, "Passed: %s", test->test_name); + if (HAS_FLAG_output_test_dir) { + DeepState_SavePassingTest(); + } + return(DeepState_TestRunPass); + } +} + /* Fork and run `test`. */ static enum DeepState_TestRunResult DeepState_ForkAndRunTest(struct DeepState_TestInfo *test) { diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 79b733f..b8a49da 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -573,7 +573,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { DeepState_Begin(test); - enum DeepState_TestRunResult result = DeepState_ForkAndRunTest(test); + enum DeepState_TestRunResult result = DeepState_RunTestLLVM(test); DeepState_Teardown(); From 95cdb135fc5fa244c20227ff354fb6efb16233fb Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 21:11:11 -0700 Subject: [PATCH 10/59] proper return value for LLVM run --- src/include/deepstate/DeepState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index f3bb41b..5721e10 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -492,7 +492,7 @@ static void DeepState_RunTest(struct DeepState_TestInfo *test) { } /* Run a test case, but in libFuzzer, so not inside a fork. */ -static void DeepState_RunTestLLVM(struct DeepState_TestInfo *test) { +static int DeepState_RunTestLLVM(struct DeepState_TestInfo *test) { /* Run the test. */ if (!setjmp(DeepState_ReturnToRun)) { /* Convert uncaught C++ exceptions into a test failure. */ From 519b61a7a99828f82f4dcab8ce605fb5573bc02b Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 21:14:54 -0700 Subject: [PATCH 11/59] Proper print format --- src/lib/DeepState.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index b8a49da..7598a02 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -549,7 +549,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; // Just ignore any too-big inputs } - printf("LLVM fuzzing with input of size %u\n", Size); + printf("LLVM fuzzing with input of size %ul\n", Size); struct DeepState_TestInfo *test = NULL; From d95dcf65e3564f37f8d3cf67ead756e72c08bf2f Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 21:27:28 -0700 Subject: [PATCH 12/59] change way memory is allocated --- src/lib/DeepState.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 7598a02..70c6d60 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -554,7 +554,9 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { struct DeepState_TestInfo *test = NULL; DeepState_InitOptions(0, ""); - DeepState_Setup(); + //DeepState_Setup(); we want to do our own, simpler, memory management + void *mem = malloc(sizeof(struct DeepState_TestRunInfo)); + DeepState_CurrentTestRun = (struct DeepState_TestRunInfo *) mem; #ifdef LIBFUZZER_WHICH_TEST for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { @@ -576,6 +578,8 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { enum DeepState_TestRunResult result = DeepState_RunTestLLVM(test); DeepState_Teardown(); + DeepState_CurrentTestRun = NULL; + free(mem); return 0; // Non-zero return values are reserved for future use. } From 9fa8c4bcf74c419b8c4718f62b607738a42403d7 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 22:13:21 -0700 Subject: [PATCH 13/59] silence deepstate output, print libFuzzer output without warning --- src/include/deepstate/Log.h | 2 ++ src/lib/DeepState.c | 4 ++-- src/lib/Log.c | 14 +++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/include/deepstate/Log.h b/src/include/deepstate/Log.h index 9fb6e14..107cd9f 100644 --- a/src/include/deepstate/Log.h +++ b/src/include/deepstate/Log.h @@ -23,6 +23,8 @@ DEEPSTATE_BEGIN_EXTERN_C +extern int DeepState_UsingLibFuzzer; + struct DeepState_Stream; struct DeepState_VarArgs { diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 70c6d60..3096fb5 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -549,8 +549,8 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; // Just ignore any too-big inputs } - printf("LLVM fuzzing with input of size %ul\n", Size); - + DeepState_UsingLibFuzzer = 1; + struct DeepState_TestInfo *test = NULL; DeepState_InitOptions(0, ""); diff --git a/src/lib/Log.c b/src/lib/Log.c index c027ac6..dca7cb2 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -64,6 +64,8 @@ enum { DeepState_LogBufSize = 4096 }; +int DeepState_UsingLibFuzzer = 0; + char DeepState_LogBuf[DeepState_LogBufSize + 1] = {}; /* Log a C string. */ @@ -144,7 +146,17 @@ int __vprintf_chk(int flag, const char *format, va_list args) { DEEPSTATE_NOINLINE int vfprintf(FILE *file, const char *format, va_list args) { - if (stderr == file) { + if (DeepState_UsingLibFuzzer) { + if (stderr == file) { + // Silence DeepState output + // DeepState_LogVFormat(DeepState_LogDebug, format, args); + } else if (stdout == file) { + // Silence DeepState output + // DeepState_LogVFormat(DeepState_LogInfo, format, args); + } else { + DeepState_LogVFormat(DeepState_LogInfo, format, args); + } + } else if (stderr == file) { DeepState_LogVFormat(DeepState_LogDebug, format, args); } else if (stdout == file) { DeepState_LogVFormat(DeepState_LogInfo, format, args); From 21a2153eb3604f48814c35c07fef7066afe2397a Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 22:24:55 -0700 Subject: [PATCH 14/59] just skip warning for now, silence later --- src/lib/Log.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index dca7cb2..c5f9ce9 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -146,24 +146,16 @@ int __vprintf_chk(int flag, const char *format, va_list args) { DEEPSTATE_NOINLINE int vfprintf(FILE *file, const char *format, va_list args) { - if (DeepState_UsingLibFuzzer) { - if (stderr == file) { - // Silence DeepState output - // DeepState_LogVFormat(DeepState_LogDebug, format, args); - } else if (stdout == file) { - // Silence DeepState output - // DeepState_LogVFormat(DeepState_LogInfo, format, args); - } else { - DeepState_LogVFormat(DeepState_LogInfo, format, args); - } - } else if (stderr == file) { + if (stderr == file) { DeepState_LogVFormat(DeepState_LogDebug, format, args); } else if (stdout == file) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { - DeepState_LogStream(DeepState_LogWarning); - DeepState_Log(DeepState_LogWarning, - "vfprintf with non-stdout/stderr stream follows:"); + if (!DeepState_UsingLibFuzzer) { + DeepState_LogStream(DeepState_LogWarning); + DeepState_Log(DeepState_LogWarning, + "vfprintf with non-stdout/stderr stream follows:"); + } DeepState_LogVFormat(DeepState_LogInfo, format, args); } return 0; From c4f533d003642628798801559e47e6f168cc9456 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 27 Jul 2018 22:52:36 -0700 Subject: [PATCH 15/59] abort on failure or crash --- src/lib/DeepState.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 3096fb5..9e4037a 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -577,6 +577,10 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { enum DeepState_TestRunResult result = DeepState_RunTestLLVM(test); + if ((result == DeepState_TestRunFail) || (result == DeepState_TestRunCrash)) { + abort(); + } + DeepState_Teardown(); DeepState_CurrentTestRun = NULL; free(mem); From 7b2fec9b3726978393a4be961020f16bcd98f390 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 00:32:43 -0700 Subject: [PATCH 16/59] don't crash on failure/crash --- src/lib/DeepState.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 9e4037a..3096fb5 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -577,10 +577,6 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { enum DeepState_TestRunResult result = DeepState_RunTestLLVM(test); - if ((result == DeepState_TestRunFail) || (result == DeepState_TestRunCrash)) { - abort(); - } - DeepState_Teardown(); DeepState_CurrentTestRun = NULL; free(mem); From 5529d560f3d95c07edf49b3bb55ced7d876f92a0 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 04:41:59 -0700 Subject: [PATCH 17/59] fix stream --- src/lib/Log.c | 5 ++++- src/lib/Stream.c | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index c5f9ce9..5fd7202 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -155,8 +155,11 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogStream(DeepState_LogWarning); DeepState_Log(DeepState_LogWarning, "vfprintf with non-stdout/stderr stream follows:"); + DeepState_LogVFormat(DeepState_LogInfo, format, args); + } else { + DeepState_LogVFormat(DeepState_LogCritical, format, args); } - DeepState_LogVFormat(DeepState_LogInfo, format, args); + } return 0; } diff --git a/src/lib/Stream.c b/src/lib/Stream.c index f6c15c9..d4250f2 100644 --- a/src/lib/Stream.c +++ b/src/lib/Stream.c @@ -563,6 +563,10 @@ static char DeepState_Format[DeepState_StreamSize + 1]; * into a */ void DeepState_StreamVFormat(enum DeepState_LogLevel level, const char *format_, va_list args) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogCritical)) { + return; // just silence anything less than a critical + } + struct DeepState_VarArgs va; va_copy(va.args, args); From dbc2adc360e7e92fbe5d6707fab503114ee39b49 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 04:45:29 -0700 Subject: [PATCH 18/59] try printf instead --- src/lib/Log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 5fd7202..9811704 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -157,7 +157,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { "vfprintf with non-stdout/stderr stream follows:"); DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { - DeepState_LogVFormat(DeepState_LogCritical, format, args); + printf(format, args); } } From a55402fe8b969930709c357d6b5f9d84378dec74 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 04:48:09 -0700 Subject: [PATCH 19/59] fix output problem --- src/lib/Log.c | 4 ++-- src/lib/Stream.c | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 9811704..745d9d0 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -155,9 +155,9 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogStream(DeepState_LogWarning); DeepState_Log(DeepState_LogWarning, "vfprintf with non-stdout/stderr stream follows:"); - DeepState_LogVFormat(DeepState_LogInfo, format, args); + DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { - printf(format, args); + DeepState_LogVFormat(DeepState_LogInfo, format, args); } } diff --git a/src/lib/Stream.c b/src/lib/Stream.c index d4250f2..f6c15c9 100644 --- a/src/lib/Stream.c +++ b/src/lib/Stream.c @@ -563,10 +563,6 @@ static char DeepState_Format[DeepState_StreamSize + 1]; * into a */ void DeepState_StreamVFormat(enum DeepState_LogLevel level, const char *format_, va_list args) { - if (DeepState_UsingLibFuzzer && (level < DeepState_LogCritical)) { - return; // just silence anything less than a critical - } - struct DeepState_VarArgs va; va_copy(va.args, args); From fcf53b25a5ec2be3f3019e54d27717bae7cd1e8b Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 08:58:45 -0700 Subject: [PATCH 20/59] try to silence logging --- src/lib/Log.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 745d9d0..6141f01 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -92,6 +92,20 @@ void DeepState_LogVFormat(enum DeepState_LogLevel level, const char *format, va_list args) { struct DeepState_VarArgs va; va_copy(va.args, args); + if (DeepState_UsingLibFuzzer && (level < DeepState_Fatal)) { + return; + } + DeepState_LogStream(level); + DeepState_StreamVFormat(level, format, va.args); + DeepState_LogStream(level); +} + +/* Log some formatted output. */ +DEEPSTATE_NOINLINE +void DeepState_LogVFormatLLVM(enum DeepState_LogLevel level, + const char *format, va_list args) { + struct DeepState_VarArgs va; + va_copy(va.args, args); DeepState_LogStream(level); DeepState_StreamVFormat(level, format, va.args); DeepState_LogStream(level); @@ -157,7 +171,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { "vfprintf with non-stdout/stderr stream follows:"); DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { - DeepState_LogVFormat(DeepState_LogInfo, format, args); + DeepState_LogVFormatLLVM(DeepState_LogInfo, format, args); } } From af6c5d8eac4b2fe4a03b20d1d754353621e1e02f Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 09:11:34 -0700 Subject: [PATCH 21/59] different approach --- src/include/deepstate/Log.h | 5 +++-- src/lib/Log.c | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/include/deepstate/Log.h b/src/include/deepstate/Log.h index 107cd9f..ea28aba 100644 --- a/src/include/deepstate/Log.h +++ b/src/include/deepstate/Log.h @@ -37,8 +37,9 @@ enum DeepState_LogLevel { DeepState_LogWarning = 2, DeepState_LogWarn = DeepState_LogWarning, DeepState_LogError = 3, - DeepState_LogFatal = 4, - DeepState_LogCritical = DeepState_LogFatal + DeepState_LogFuzzer = 4, + DeepState_LogFatal = 5, + DeepState_LogCritical = DeepState_LogFatal, }; /* Log a C string. */ diff --git a/src/lib/Log.c b/src/lib/Log.c index 6141f01..4d5ab65 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -53,6 +53,8 @@ static const char *DeepState_LogLevelStr(enum DeepState_LogLevel level) { return "WARNING"; case DeepState_LogError: return "ERROR"; + case DeepState_LogFuzzer: + return "FUZZER"; case DeepState_LogFatal: return "FATAL"; default: @@ -71,6 +73,9 @@ char DeepState_LogBuf[DeepState_LogBufSize + 1] = {}; /* Log a C string. */ DEEPSTATE_NOINLINE void DeepState_Log(enum DeepState_LogLevel level, const char *str) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogFatal)) { + return; + } memset(DeepState_LogBuf, 0, DeepState_LogBufSize); snprintf(DeepState_LogBuf, DeepState_LogBufSize, "%s: %s\n", DeepState_LogLevelStr(level), str); @@ -165,15 +170,14 @@ int vfprintf(FILE *file, const char *format, va_list args) { } else if (stdout == file) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { - if (!DeepState_UsingLibFuzzer) { - DeepState_LogStream(DeepState_LogWarning); - DeepState_Log(DeepState_LogWarning, - "vfprintf with non-stdout/stderr stream follows:"); - DeepState_LogVFormat(DeepState_LogInfo, format, args); - } else { - DeepState_LogVFormatLLVM(DeepState_LogInfo, format, args); - } - +#ifndef LIBFUZZER + DeepState_LogStream(DeepState_LogWarning); + DeepState_Log(DeepState_LogWarning, + "vfprintf with non-stdout/stderr stream follows:"); + DeepState_LogVFormat(DeepState_LogInfo, format, args); +#else + DeepState_LogVFormat(DeepState_LogFuzzer, format, args); +#endif } return 0; } From e263f466965ad4572e89b02820edb209df3ddd36 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 09:14:38 -0700 Subject: [PATCH 22/59] fix logging level name --- src/lib/Log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 4d5ab65..e0095e1 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -97,7 +97,7 @@ void DeepState_LogVFormat(enum DeepState_LogLevel level, const char *format, va_list args) { struct DeepState_VarArgs va; va_copy(va.args, args); - if (DeepState_UsingLibFuzzer && (level < DeepState_Fatal)) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogFatal)) { return; } DeepState_LogStream(level); From e4db87695941d347521de164dabb2c7d30859bad Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 09:18:14 -0700 Subject: [PATCH 23/59] try logging as fuzzer --- src/lib/Log.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index e0095e1..efe9287 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -170,14 +170,14 @@ int vfprintf(FILE *file, const char *format, va_list args) { } else if (stdout == file) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { -#ifndef LIBFUZZER - DeepState_LogStream(DeepState_LogWarning); - DeepState_Log(DeepState_LogWarning, - "vfprintf with non-stdout/stderr stream follows:"); - DeepState_LogVFormat(DeepState_LogInfo, format, args); -#else - DeepState_LogVFormat(DeepState_LogFuzzer, format, args); -#endif + if (!DeepState_UsingLibFuzzer) { + DeepState_LogStream(DeepState_LogWarning); + DeepState_Log(DeepState_LogWarning, + "vfprintf with non-stdout/stderr stream follows:"); + DeepState_LogVFormat(DeepState_LogInfo, format, args); + } else { + DeepState_LogVFormat(DeepState_LogFuzzer, format, args); + } } return 0; } From 3a778828354279f46fa1194ee7a100ace54e5a61 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 09:20:15 -0700 Subject: [PATCH 24/59] log only fuzzer info --- src/lib/Log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index efe9287..ea890ca 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -73,7 +73,7 @@ char DeepState_LogBuf[DeepState_LogBufSize + 1] = {}; /* Log a C string. */ DEEPSTATE_NOINLINE void DeepState_Log(enum DeepState_LogLevel level, const char *str) { - if (DeepState_UsingLibFuzzer && (level < DeepState_LogFatal)) { + if (DeepState_UsingLibFuzzer && (level != DeepState_LogFuzzer)) { return; } memset(DeepState_LogBuf, 0, DeepState_LogBufSize); @@ -97,7 +97,7 @@ void DeepState_LogVFormat(enum DeepState_LogLevel level, const char *format, va_list args) { struct DeepState_VarArgs va; va_copy(va.args, args); - if (DeepState_UsingLibFuzzer && (level < DeepState_LogFatal)) { + if (DeepState_UsingLibFuzzer && (level != DeepState_LogFuzzer)) { return; } DeepState_LogStream(level); From 78a99537c0ff2455f4108ec10a50204a7746380a Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 09:22:30 -0700 Subject: [PATCH 25/59] Also log fatals --- src/lib/Log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index ea890ca..157c623 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -73,7 +73,7 @@ char DeepState_LogBuf[DeepState_LogBufSize + 1] = {}; /* Log a C string. */ DEEPSTATE_NOINLINE void DeepState_Log(enum DeepState_LogLevel level, const char *str) { - if (DeepState_UsingLibFuzzer && (level != DeepState_LogFuzzer)) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogFuzzer)) { return; } memset(DeepState_LogBuf, 0, DeepState_LogBufSize); @@ -97,7 +97,7 @@ void DeepState_LogVFormat(enum DeepState_LogLevel level, const char *format, va_list args) { struct DeepState_VarArgs va; va_copy(va.args, args); - if (DeepState_UsingLibFuzzer && (level != DeepState_LogFuzzer)) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogFuzzer)) { return; } DeepState_LogStream(level); From 5e9c208c3bdc11a60df4128d46c3851f048d47d1 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 12:27:07 -0700 Subject: [PATCH 26/59] better logging --- src/lib/Log.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 157c623..947be0d 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -171,10 +171,15 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { if (!DeepState_UsingLibFuzzer) { - DeepState_LogStream(DeepState_LogWarning); - DeepState_Log(DeepState_LogWarning, - "vfprintf with non-stdout/stderr stream follows:"); - DeepState_LogVFormat(DeepState_LogInfo, format, args); + if (strnstr(format, "INFO: ", 7) == 0) { + // Assume such a string to an nonstd target is libFuzzer + DeepState_LogVFormat(DeepState_LogFuzzer, format, args); + } else { + DeepState_LogStream(DeepState_LogWarning); + DeepState_Log(DeepState_LogWarning, + "vfprintf with non-stdout/stderr stream follows:"); + DeepState_LogVFormat(DeepState_LogInfo, format, args); + } } else { DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } From 6418a5cd16b5b6634e794fd5df749fec5f73482f Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 12:29:38 -0700 Subject: [PATCH 27/59] strnstr not available --- src/lib/Log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 947be0d..ab16c49 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -171,7 +171,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { if (!DeepState_UsingLibFuzzer) { - if (strnstr(format, "INFO: ", 7) == 0) { + if (strstr(format, "INFO: ") == 0) { // Assume such a string to an nonstd target is libFuzzer DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } else { From 1343cecfc28b3652acc28e0f3f4ceceb1fa68fd5 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 12:35:19 -0700 Subject: [PATCH 28/59] correct check for INFO --- src/lib/Log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index ab16c49..78ef485 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -171,7 +171,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { if (!DeepState_UsingLibFuzzer) { - if (strstr(format, "INFO: ") == 0) { + if (strstr(format, "INFO: ") == format) { // Assume such a string to an nonstd target is libFuzzer DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } else { From d4e2225727c767c419d6aa5ae8b71fc5f3f51b4a Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 12:36:54 -0700 Subject: [PATCH 29/59] correct check for INFO to just look for INFO: --- src/lib/Log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 78ef485..7ffe5ef 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -171,7 +171,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { if (!DeepState_UsingLibFuzzer) { - if (strstr(format, "INFO: ") == format) { + if (strstr(format, "INFO: ") != NULL) { // Assume such a string to an nonstd target is libFuzzer DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } else { From 8fe58fe48ef017362f35263cb959d11f8b507d47 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 12:40:25 -0700 Subject: [PATCH 30/59] log as external --- src/lib/Log.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index 7ffe5ef..ca6e779 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -54,7 +54,7 @@ static const char *DeepState_LogLevelStr(enum DeepState_LogLevel level) { case DeepState_LogError: return "ERROR"; case DeepState_LogFuzzer: - return "FUZZER"; + return "EXTERNAL"; case DeepState_LogFatal: return "FATAL"; default: @@ -170,8 +170,13 @@ int vfprintf(FILE *file, const char *format, va_list args) { } else if (stdout == file) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { + DeepState_LogVFormat(DeepState_LogFuzzer, format, args); + } + /* + Old code. Now let's just log everything with odd dest as "external." + if (!DeepState_UsingLibFuzzer) { - if (strstr(format, "INFO: ") != NULL) { + if (strstr(format, "INFO:") != NULL) { // Assume such a string to an nonstd target is libFuzzer DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } else { @@ -183,6 +188,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { } else { DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } + */ } return 0; } From 3fe716fbf0d3c871729617b272c3825b4b577816 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 12:41:14 -0700 Subject: [PATCH 31/59] fix extra brace --- src/lib/Log.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/Log.c b/src/lib/Log.c index ca6e779..6605b41 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -189,7 +189,6 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogVFormat(DeepState_LogFuzzer, format, args); } */ - } return 0; } From 04286865816ee39c672e8ac6a278b76c344dbfd7 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 18:04:19 -0700 Subject: [PATCH 32/59] let python know about new logging level --- bin/deepstate/common.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/deepstate/common.py b/bin/deepstate/common.py index 0de6ffc..8e479da 100644 --- a/bin/deepstate/common.py +++ b/bin/deepstate/common.py @@ -35,7 +35,8 @@ LOG_LEVEL_DEBUG = 0 LOG_LEVEL_INFO = 1 LOG_LEVEL_WARNING = 2 LOG_LEVEL_ERROR = 3 -LOG_LEVEL_FATAL = 4 +LOG_LEVEL_FUZZER = 4 +LOG_LEVEL_FATAL = 5 LOGGER = logging.getLogger("deepstate") From 9d8889e3f2693f8a3c88f941571fdc2d8bf49078 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Sat, 28 Jul 2018 18:06:07 -0700 Subject: [PATCH 33/59] change name to external, let python konw about new level --- bin/deepstate/common.py | 2 +- src/include/deepstate/Log.h | 2 +- src/lib/Log.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bin/deepstate/common.py b/bin/deepstate/common.py index 8e479da..8ca19ee 100644 --- a/bin/deepstate/common.py +++ b/bin/deepstate/common.py @@ -35,7 +35,7 @@ LOG_LEVEL_DEBUG = 0 LOG_LEVEL_INFO = 1 LOG_LEVEL_WARNING = 2 LOG_LEVEL_ERROR = 3 -LOG_LEVEL_FUZZER = 4 +LOG_LEVEL_EXTERNAL = 4 LOG_LEVEL_FATAL = 5 diff --git a/src/include/deepstate/Log.h b/src/include/deepstate/Log.h index ea28aba..8cb2767 100644 --- a/src/include/deepstate/Log.h +++ b/src/include/deepstate/Log.h @@ -37,7 +37,7 @@ enum DeepState_LogLevel { DeepState_LogWarning = 2, DeepState_LogWarn = DeepState_LogWarning, DeepState_LogError = 3, - DeepState_LogFuzzer = 4, + DeepState_LogExternal = 4, DeepState_LogFatal = 5, DeepState_LogCritical = DeepState_LogFatal, }; diff --git a/src/lib/Log.c b/src/lib/Log.c index 6605b41..cbcb03f 100644 --- a/src/lib/Log.c +++ b/src/lib/Log.c @@ -53,7 +53,7 @@ static const char *DeepState_LogLevelStr(enum DeepState_LogLevel level) { return "WARNING"; case DeepState_LogError: return "ERROR"; - case DeepState_LogFuzzer: + case DeepState_LogExternal: return "EXTERNAL"; case DeepState_LogFatal: return "FATAL"; @@ -73,7 +73,7 @@ char DeepState_LogBuf[DeepState_LogBufSize + 1] = {}; /* Log a C string. */ DEEPSTATE_NOINLINE void DeepState_Log(enum DeepState_LogLevel level, const char *str) { - if (DeepState_UsingLibFuzzer && (level < DeepState_LogFuzzer)) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogExternal)) { return; } memset(DeepState_LogBuf, 0, DeepState_LogBufSize); @@ -97,7 +97,7 @@ void DeepState_LogVFormat(enum DeepState_LogLevel level, const char *format, va_list args) { struct DeepState_VarArgs va; va_copy(va.args, args); - if (DeepState_UsingLibFuzzer && (level < DeepState_LogFuzzer)) { + if (DeepState_UsingLibFuzzer && (level < DeepState_LogExternal)) { return; } DeepState_LogStream(level); @@ -170,7 +170,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { } else if (stdout == file) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } else { - DeepState_LogVFormat(DeepState_LogFuzzer, format, args); + DeepState_LogVFormat(DeepState_LogExternal, format, args); } /* Old code. Now let's just log everything with odd dest as "external." @@ -178,7 +178,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { if (!DeepState_UsingLibFuzzer) { if (strstr(format, "INFO:") != NULL) { // Assume such a string to an nonstd target is libFuzzer - DeepState_LogVFormat(DeepState_LogFuzzer, format, args); + DeepState_LogVFormat(DeepState_LogExternal, format, args); } else { DeepState_LogStream(DeepState_LogWarning); DeepState_Log(DeepState_LogWarning, @@ -186,7 +186,7 @@ int vfprintf(FILE *file, const char *format, va_list args) { DeepState_LogVFormat(DeepState_LogInfo, format, args); } } else { - DeepState_LogVFormat(DeepState_LogFuzzer, format, args); + DeepState_LogVFormat(DeepState_LogExternal, format, args); } */ return 0; From d1a4417dabb726d2dd60c6f1f9500a27d1dddd22 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 19:30:10 -0700 Subject: [PATCH 34/59] Add LibFuzzer to makefile --- CMakeLists.txt | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 64cfe8a..ed32e5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,12 @@ cmake_minimum_required(VERSION 2.8) enable_language(C) enable_language(CXX) +set(BUILD_LIBFUZZER "$ENV{BUILD_LIBFUZZER}") +if (BUILD_LIBFUZZER) + SET(CMAKE_C_COMPILER clang-6.0) + SET(CMAKE_CXX_COMPILER clang++-6.0) +endif () + set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(NOT CMAKE_BUILD_TYPE) @@ -71,7 +77,7 @@ target_include_directories(${PROJECT_NAME}32 PUBLIC SYSTEM "${CMAKE_SOURCE_DIR}/src/include" ) -# Install the +# Install the library install( DIRECTORY "${CMAKE_SOURCE_DIR}/src/include/deepstate" DESTINATION include @@ -84,6 +90,28 @@ install( ARCHIVE DESTINATION lib ) +if (BUILD_LIBFUZZER) + add_library(${PROJECT_NAME}_LF STATIC + src/lib/DeepState.c + src/lib/Log.c + src/lib/Option.c + src/lib/Stream.c + ) + + target_compile_options(${PROJECT_NAME}_LF PUBLIC -mno-avx -fsanitize=fuzzer-no-link) + + target_include_directories(${PROJECT_NAME}_LF + PUBLIC SYSTEM "${CMAKE_SOURCE_DIR}/src/include" + ) + + install( + TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_LF + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) +endif () + + set(SETUP_PY_IN "${CMAKE_SOURCE_DIR}/bin/setup.py.in") set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") configure_file(${SETUP_PY_IN} ${SETUP_PY}) From 1aef3fd325bef86c9312c7d7381588d47644d79b Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:21:33 -0700 Subject: [PATCH 35/59] examples with libfuzzer --- CMakeLists.txt | 6 +++--- examples/CMakeLists.txt | 8 +++++++- examples/OneOf.cpp | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed32e5f..b7afade 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ set(BUILD_LIBFUZZER "$ENV{BUILD_LIBFUZZER}") if (BUILD_LIBFUZZER) SET(CMAKE_C_COMPILER clang-6.0) SET(CMAKE_CXX_COMPILER clang++-6.0) -endif () +endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -45,7 +45,7 @@ set(CMAKE_CXX_EXTENSIONS ON) if (NOT WIN32) set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 11) -endif () +endif() add_library(${PROJECT_NAME} STATIC src/lib/DeepState.c @@ -109,7 +109,7 @@ if (BUILD_LIBFUZZER) LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) -endif () +endif() set(SETUP_PY_IN "${CMAKE_SOURCE_DIR}/bin/setup.py.in") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 295d7b5..3eacea1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,9 +16,15 @@ add_executable(Crash Crash.cpp) target_link_libraries(Crash deepstate) -add_executable(OneOf OneOf.cpp) +add_executable(OneOf OneOf.cpp) target_link_libraries(OneOf deepstate) +if (BUILD_LIBFUZZER) + add_executable(OneOfLF OneOf.cpp) + target_link_libraries(OneOf_LF deepstate_LF) + set_target_properties(OneOf_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(Fixture Fixture.cpp) target_link_libraries(Fixture deepstate) diff --git a/examples/OneOf.cpp b/examples/OneOf.cpp index 1a9bddf..46cd551 100644 --- a/examples/OneOf.cpp +++ b/examples/OneOf.cpp @@ -64,7 +64,9 @@ TEST(OneOfExample, ProduceSixtyOrHigher) { } } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif From 2ceaa1173dd213f8b954b50188e43021740a21fb Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:22:29 -0700 Subject: [PATCH 36/59] fix OneOF target name --- examples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3eacea1..1f72d7f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,7 +20,7 @@ add_executable(OneOf OneOf.cpp) target_link_libraries(OneOf deepstate) if (BUILD_LIBFUZZER) - add_executable(OneOfLF OneOf.cpp) + add_executable(OneOf_LF OneOf.cpp) target_link_libraries(OneOf_LF deepstate_LF) set_target_properties(OneOf_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") endif() From 3006e198170ff07217669a9efefba7b0bd2ce9e8 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:24:39 -0700 Subject: [PATCH 37/59] proper link --- examples/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1f72d7f..2046f41 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(OneOf deepstate) if (BUILD_LIBFUZZER) add_executable(OneOf_LF OneOf.cpp) target_link_libraries(OneOf_LF deepstate_LF) + target_link_libraries (OneOf_LF "-fsanitize=fuzzer") set_target_properties(OneOf_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") endif() From c23e4e20b57f804e04efeca8c2052c0c6d4ed482 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:31:41 -0700 Subject: [PATCH 38/59] Libfuzzerize all examples --- examples/CMakeLists.txt | 56 +++++++++++++++++++++++++++++ examples/Crash.cpp | 2 ++ examples/Euler.cpp | 2 ++ examples/Fixture.cpp | 3 +- examples/IntegerArithmetic.cpp | 2 ++ examples/IntegerOverflow.cpp | 2 ++ examples/Lists.cpp | 2 ++ examples/Primes.cpp | 3 +- examples/StreamingAndFormatting.cpp | 2 ++ 9 files changed, 72 insertions(+), 2 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2046f41..ab5ec63 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,6 +16,13 @@ add_executable(Crash Crash.cpp) target_link_libraries(Crash deepstate) +if (BUILD_LIBFUZZER) + add_executable(Crash_LF Crash.cpp) + target_link_libraries(Crash_LF deepstate_LF) + target_link_libraries (Crash_LF "-fsanitize=fuzzer") + set_target_properties(Crash_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(OneOf OneOf.cpp) target_link_libraries(OneOf deepstate) @@ -29,24 +36,73 @@ endif() add_executable(Fixture Fixture.cpp) target_link_libraries(Fixture deepstate) +if (BUILD_LIBFUZZER) + add_executable(Fixture_LF Fixture.cpp) + target_link_libraries(Fixture_LF deepstate_LF) + target_link_libraries (Fixture_LF "-fsanitize=fuzzer") + set_target_properties(Fixture_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(Primes Primes.cpp) target_link_libraries(Primes deepstate) +if (BUILD_LIBFUZZER) + add_executable(Primes_LF Primes.cpp) + target_link_libraries(Primes_LF deepstate_LF) + target_link_libraries (Primes_LF "-fsanitize=fuzzer") + set_target_properties(Primes_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(Euler Euler.cpp) target_link_libraries(Euler deepstate) +if (BUILD_LIBFUZZER) + add_executable(Euler_LF Euler.cpp) + target_link_libraries(Euler_LF deepstate_LF) + target_link_libraries (Euler_LF "-fsanitize=fuzzer") + set_target_properties(Euler_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(IntegerOverflow IntegerOverflow.cpp) target_link_libraries(IntegerOverflow deepstate) +if (BUILD_LIBFUZZER) + add_executable(IntegerOverflow_LF IntegerOverflow.cpp) + target_link_libraries(IntegerOverflow_LF deepstate_LF) + target_link_libraries (IntegerOverflow_LF "-fsanitize=fuzzer") + set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(IntegerArithmetic IntegerArithmetic.cpp) target_link_libraries(IntegerArithmetic deepstate) +if (BUILD_LIBFUZZER) + add_executable(IntegerArithmetic_LF IntegerArithmetic.cpp) + target_link_libraries(IntegerArithmetic_LF deepstate_LF) + target_link_libraries (IntegerArithmetic_LF "-fsanitize=fuzzer") + set_target_properties(IntegerArithmetic_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(Lists Lists.cpp) target_link_libraries(Lists deepstate) +if (BUILD_LIBFUZZER) + add_executable(Lists_LF Lists.cpp) + target_link_libraries(Lists_LF deepstate_LF) + target_link_libraries (Lists_LF "-fsanitize=fuzzer") + set_target_properties(Lists_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(StreamingAndFormatting StreamingAndFormatting.cpp) target_link_libraries(StreamingAndFormatting deepstate) +if (BUILD_LIBFUZZER) + add_executable(StreamingAndFormatting_LF StreamingAndFormatting.cpp) + target_link_libraries(StreamingAndFormatting_LF deepstate_LF) + target_link_libraries (StreamingAndFormatting_LF "-fsanitize=fuzzer") + set_target_properties(StreamingAndFormatting_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") +endif() + add_executable(Squares Squares.c) target_link_libraries(Squares deepstate) set_target_properties(Squares PROPERTIES COMPILE_DEFINITIONS "DEEPSTATE_TEST") diff --git a/examples/Crash.cpp b/examples/Crash.cpp index ca0e66f..7aa1fc5 100644 --- a/examples/Crash.cpp +++ b/examples/Crash.cpp @@ -36,7 +36,9 @@ TEST(Crash, SegFault) { ASSERT_EQ(x, x); } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif diff --git a/examples/Euler.cpp b/examples/Euler.cpp index 20f9790..8f2dd0d 100644 --- a/examples/Euler.cpp +++ b/examples/Euler.cpp @@ -39,7 +39,9 @@ TEST(Euler, SumsOfLikePowers) { << "^5 + " << d << "^5 = " << e << "^5"; } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif diff --git a/examples/Fixture.cpp b/examples/Fixture.cpp index a4af0e1..2c864c6 100644 --- a/examples/Fixture.cpp +++ b/examples/Fixture.cpp @@ -36,8 +36,9 @@ TEST_F(MyTest, Something) { ASSUME_NE(x, 0); } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } - +#endif diff --git a/examples/IntegerArithmetic.cpp b/examples/IntegerArithmetic.cpp index 37b2ac0..7af644d 100644 --- a/examples/IntegerArithmetic.cpp +++ b/examples/IntegerArithmetic.cpp @@ -45,7 +45,9 @@ TEST(Arithmetic, InvertibleMultiplication_CanFail) { }); } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif diff --git a/examples/IntegerOverflow.cpp b/examples/IntegerOverflow.cpp index 09fd32f..c5add45 100644 --- a/examples/IntegerOverflow.cpp +++ b/examples/IntegerOverflow.cpp @@ -40,7 +40,9 @@ TEST(SignedInteger, MultiplicationOverflow) { << x << " squared overflowed."; } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif diff --git a/examples/Lists.cpp b/examples/Lists.cpp index 1e4ad12..8d21f6c 100644 --- a/examples/Lists.cpp +++ b/examples/Lists.cpp @@ -31,7 +31,9 @@ TEST(Vector, DoubleReversal) { }); } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); DeepState_Run(); } +#endif diff --git a/examples/Primes.cpp b/examples/Primes.cpp index 161527d..1401d35 100644 --- a/examples/Primes.cpp +++ b/examples/Primes.cpp @@ -53,8 +53,9 @@ TEST(PrimePolynomial, OnlyGeneratesPrimes_NoStreaming) { DeepState_Assert(IsPrime(Pump(poly))); } - +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif diff --git a/examples/StreamingAndFormatting.cpp b/examples/StreamingAndFormatting.cpp index f2fb956..f34c8fe 100644 --- a/examples/StreamingAndFormatting.cpp +++ b/examples/StreamingAndFormatting.cpp @@ -40,7 +40,9 @@ TEST(Formatting, OverridePrintf) { printf("hello again!"); } +#ifndef LIBFUZZER int main(int argc, char *argv[]) { DeepState_InitOptions(argc, argv); return DeepState_Run(); } +#endif From eea3248bfc4bbc48e4692a88934da32b649f46f5 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:43:55 -0700 Subject: [PATCH 39/59] update readme, fix first/last test, change clang --- CMakeLists.txt | 4 ++-- README.md | 16 +++++++++++++--- src/include/deepstate/DeepState.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7afade..de68a02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,8 @@ enable_language(CXX) set(BUILD_LIBFUZZER "$ENV{BUILD_LIBFUZZER}") if (BUILD_LIBFUZZER) - SET(CMAKE_C_COMPILER clang-6.0) - SET(CMAKE_CXX_COMPILER clang++-6.0) + SET(CMAKE_C_COMPILER clang) + SET(CMAKE_CXX_COMPILER clang++) endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/README.md b/README.md index 7afe4f3..ab36939 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,19 @@ deepstate-angr --num_workers 4 --output_test_dir out $DEEPSTATE/build/examples/I DeepState consists of a static library, used to write test harnesses, and command-line _executors_ written in Python. At this time, the best documentation is in the [examples](/examples) and in our [paper](https://agroce.github.io/bar18.pdf). -## Fuzzing +## Fuzzing with libFuzzer -DeepState now can be used with a file-based fuzzer (e.g. AFL). There +If you install a recent-enough clang, and run `cmake` when you install +with `BUILD_LIBFUZZER` defined, you can generate tests using LlibFuzzer. +Because both DeepState and libFuzzer want to be `main`, this requires +building a different executable for libFuzzer. The `examples` +directory shows how this can be done. The libFuzzer executable works +like any other libFuzzer executable, and the tests produced can be run +using the normal DeepState executable. + +## Fuzzing with AFL + +DeepState can also be used with a file-based fuzzer (e.g. AFL). There are a few steps to this. First, compile DeepState itself with any needed instrumentation. E.g., to use it with AFL, you might want to add something like: @@ -128,7 +138,7 @@ Finally, if an example has more than one test, you need to specify, with a fully qualified name (e.g., `Arithmetic_InvertibleMultiplication_CanFail`), which test to run, using the `--input_which_test` flag to the binary. By -default, DeepState will run the first test defined. +default, DeepState will run the last test defined. You can compile with `afl-clang-fast` and `afl-clang-fast++` for deferred instrumentation. You'll need code like: diff --git a/src/include/deepstate/DeepState.h b/src/include/deepstate/DeepState.h index 5721e10..17dd324 100644 --- a/src/include/deepstate/DeepState.h +++ b/src/include/deepstate/DeepState.h @@ -692,7 +692,7 @@ static int DeepState_RunSingleSavedTestDir(void) { } } else { DeepState_LogFormat(DeepState_LogInfo, - "No test specified, defaulting to first test"); + "No test specified, defaulting to last test defined"); break; } } From 711cd7ed3def08f56746fef97363f925ae3d240c Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:50:56 -0700 Subject: [PATCH 40/59] add other overflow test --- examples/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ab5ec63..7b22b6d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -71,6 +71,12 @@ if (BUILD_LIBFUZZER) target_link_libraries(IntegerOverflow_LF deepstate_LF) target_link_libraries (IntegerOverflow_LF "-fsanitize=fuzzer") set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") + + add_executable(IntegerOverflow_Addition_LF IntegerArithmetic.cpp) + target_link_libraries(IntegerOverflow_LF deepstate_LF) + target_link_libraries (IntegerOverflow_LF "-fsanitize=fuzzer") + set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS + "LIBFUZZER LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() add_executable(IntegerArithmetic IntegerArithmetic.cpp) From 717221836f772a162974404f6fe7b0aaace3a47b Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:52:38 -0700 Subject: [PATCH 41/59] fix missing _Addition --- examples/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7b22b6d..774d7c8 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -73,9 +73,9 @@ if (BUILD_LIBFUZZER) set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") add_executable(IntegerOverflow_Addition_LF IntegerArithmetic.cpp) - target_link_libraries(IntegerOverflow_LF deepstate_LF) - target_link_libraries (IntegerOverflow_LF "-fsanitize=fuzzer") - set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS + target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) + target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") + set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() From 7b403bbc8f8b24da72fc932a4306f00e681fd9e8 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:53:53 -0700 Subject: [PATCH 42/59] fix cmakelists --- examples/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 774d7c8..70c4354 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -75,8 +75,8 @@ if (BUILD_LIBFUZZER) add_executable(IntegerOverflow_Addition_LF IntegerArithmetic.cpp) target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") - set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS - "LIBFUZZER LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") + set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") + set_target_properties(IntegerOverflow_Addition_LF "LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() add_executable(IntegerArithmetic IntegerArithmetic.cpp) From 763d106a7ade2559d45ed498a37c3b5095e16332 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:54:27 -0700 Subject: [PATCH 43/59] fix cmakelists --- examples/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 70c4354..98e3ebd 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -76,7 +76,8 @@ if (BUILD_LIBFUZZER) target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") - set_target_properties(IntegerOverflow_Addition_LF "LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") + set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS + "LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() add_executable(IntegerArithmetic IntegerArithmetic.cpp) From 805e5026ea59f76b775d07bc35884f7788f4bd6d Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:55:15 -0700 Subject: [PATCH 44/59] fix cmakelists --- examples/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 98e3ebd..fc0a541 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -75,9 +75,8 @@ if (BUILD_LIBFUZZER) add_executable(IntegerOverflow_Addition_LF IntegerArithmetic.cpp) target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") - set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS - "LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") + "LIBFUZZER,LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() add_executable(IntegerArithmetic IntegerArithmetic.cpp) From b25efe48a6451aab9611b730239f3c4179baf406 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:57:10 -0700 Subject: [PATCH 45/59] compile the right file --- examples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index fc0a541..54ed94b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -72,7 +72,7 @@ if (BUILD_LIBFUZZER) target_link_libraries (IntegerOverflow_LF "-fsanitize=fuzzer") set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") - add_executable(IntegerOverflow_Addition_LF IntegerArithmetic.cpp) + add_executable(IntegerOverflow_Addition_LF IntegerOverflow.cpp) target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS From dfe450dcf17910d5819609e57add6634298903f5 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:59:18 -0700 Subject: [PATCH 46/59] proper delimiter --- examples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 54ed94b..f873195 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -76,7 +76,7 @@ if (BUILD_LIBFUZZER) target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS - "LIBFUZZER,LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") + "LIBFUZZER;LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() add_executable(IntegerArithmetic IntegerArithmetic.cpp) From 121a748f7e8e8e17ac9fe515d760527ab53e26bb Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 21:59:29 -0700 Subject: [PATCH 47/59] add mention of test control --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ab36939..2a76fcf 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,10 @@ directory shows how this can be done. The libFuzzer executable works like any other libFuzzer executable, and the tests produced can be run using the normal DeepState executable. +Because libFuzzer controls `main`, you need a different executable for +each test when using libFuzzer, which can be done as shown in the compilation for the +`IntegerOverflow` example. + ## Fuzzing with AFL DeepState can also be used with a file-based fuzzer (e.g. AFL). There From 656ffa1b6da417475944c16720f2d2773c29d8d2 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 22:05:56 -0700 Subject: [PATCH 48/59] new way to specify which test --- README.md | 4 ---- examples/CMakeLists.txt | 6 ------ src/lib/DeepState.c | 16 +++++++++------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2a76fcf..ab36939 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,6 @@ directory shows how this can be done. The libFuzzer executable works like any other libFuzzer executable, and the tests produced can be run using the normal DeepState executable. -Because libFuzzer controls `main`, you need a different executable for -each test when using libFuzzer, which can be done as shown in the compilation for the -`IntegerOverflow` example. - ## Fuzzing with AFL DeepState can also be used with a file-based fuzzer (e.g. AFL). There diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f873195..ab5ec63 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -71,12 +71,6 @@ if (BUILD_LIBFUZZER) target_link_libraries(IntegerOverflow_LF deepstate_LF) target_link_libraries (IntegerOverflow_LF "-fsanitize=fuzzer") set_target_properties(IntegerOverflow_LF PROPERTIES COMPILE_DEFINITIONS "LIBFUZZER") - - add_executable(IntegerOverflow_Addition_LF IntegerOverflow.cpp) - target_link_libraries(IntegerOverflow_Addition_LF deepstate_LF) - target_link_libraries (IntegerOverflow_Addition_LF "-fsanitize=fuzzer") - set_target_properties(IntegerOverflow_Addition_LF PROPERTIES COMPILE_DEFINITIONS - "LIBFUZZER;LIBFUZZER_WHICH_TEST=\"SignedInteger_AdditionOverflow\"") endif() add_executable(IntegerArithmetic IntegerArithmetic.cpp) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 3096fb5..99e7e51 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -558,15 +558,17 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { void *mem = malloc(sizeof(struct DeepState_TestRunInfo)); DeepState_CurrentTestRun = (struct DeepState_TestRunInfo *) mem; -#ifdef LIBFUZZER_WHICH_TEST - for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { - if (strncmp(LIBFUZZER_WHICH_TEST, test->test_name, strlen(FLAGS_input_which_test)) == 0) { - break; + const char* which_test = getenv("LIBFUZZER_WHICH_TEST"); + if (!(strnlen(which_test, 1024) == 0)) { + for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { + if (strncmp(which_test, test->test_name, strnlen(which_test, 1024)) == 0) { + break; + } } + } else + test = DeepState_FirstTest(); } -#else - test = DeepState_FirstTest(); -#endif + memset((void *) DeepState_Input, 0, sizeof(DeepState_Input)); DeepState_InputIndex = 0; From 0943f812a05a8be9bc15b4ddece91e19be6e7a12 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 22:07:59 -0700 Subject: [PATCH 49/59] fix env read --- src/lib/DeepState.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index 99e7e51..efc8ac6 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -558,6 +558,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { void *mem = malloc(sizeof(struct DeepState_TestRunInfo)); DeepState_CurrentTestRun = (struct DeepState_TestRunInfo *) mem; + test = DeepState_FirstTest(); const char* which_test = getenv("LIBFUZZER_WHICH_TEST"); if (!(strnlen(which_test, 1024) == 0)) { for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { @@ -565,11 +566,8 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { break; } } - } else - test = DeepState_FirstTest(); } - memset((void *) DeepState_Input, 0, sizeof(DeepState_Input)); DeepState_InputIndex = 0; From 6a9dadcf7ac517165c37af0f18aacb5824cb3483 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 22:09:39 -0700 Subject: [PATCH 50/59] fix read of null --- src/lib/DeepState.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/DeepState.c b/src/lib/DeepState.c index efc8ac6..db3a0ed 100644 --- a/src/lib/DeepState.c +++ b/src/lib/DeepState.c @@ -560,7 +560,7 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { test = DeepState_FirstTest(); const char* which_test = getenv("LIBFUZZER_WHICH_TEST"); - if (!(strnlen(which_test, 1024) == 0)) { + if (which_test != NULL) { for (test = DeepState_FirstTest(); test != NULL; test = test->prev) { if (strncmp(which_test, test->test_name, strnlen(which_test, 1024)) == 0) { break; From f88ee36aea0ae3d1159224f2506071860c6ee0dc Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 22:11:41 -0700 Subject: [PATCH 51/59] how to set the test --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab36939..2ba8977 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,9 @@ Because both DeepState and libFuzzer want to be `main`, this requires building a different executable for libFuzzer. The `examples` directory shows how this can be done. The libFuzzer executable works like any other libFuzzer executable, and the tests produced can be run -using the normal DeepState executable. +using the normal DeepState executable. Use the `LIBFUZZER_WHICH_TEST` +environment variable to control which test libFuzzer runs, using a +fully qualified name (e.g., `Arithmetic_InvertibleMultiplication_CanFail`). ## Fuzzing with AFL From 99dc4270c39c4c1474f7e4e6ad37bd7227a59e49 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 22:33:06 -0700 Subject: [PATCH 52/59] more info on using libfuzzer --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ba8977..f9afde0 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,17 @@ Because both DeepState and libFuzzer want to be `main`, this requires building a different executable for libFuzzer. The `examples` directory shows how this can be done. The libFuzzer executable works like any other libFuzzer executable, and the tests produced can be run -using the normal DeepState executable. Use the `LIBFUZZER_WHICH_TEST` +using the normal DeepState executable. For example, generating some +tests of the `OneOf` example (up to 5,000 runs), then running those +tests to examine the results, would look like: + +```shell +mkdir OneOf_corpus +./OneOf_LF OneOf_libFuzzer_corpus --runs 5000 +/OneOf --input_test_files_dir OneOf_libFuzzer_corpus +``` + +Use the `LIBFUZZER_WHICH_TEST` environment variable to control which test libFuzzer runs, using a fully qualified name (e.g., `Arithmetic_InvertibleMultiplication_CanFail`). From 42c983d5cc467bd9b065e43f71096605dad62e5a Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Mon, 30 Jul 2018 22:33:48 -0700 Subject: [PATCH 53/59] add dot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9afde0..3b884b4 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ tests to examine the results, would look like: ```shell mkdir OneOf_corpus ./OneOf_LF OneOf_libFuzzer_corpus --runs 5000 -/OneOf --input_test_files_dir OneOf_libFuzzer_corpus +./OneOf --input_test_files_dir OneOf_libFuzzer_corpus ``` Use the `LIBFUZZER_WHICH_TEST` From 0cd1011ba2fc877b7d902f1a80374c71d792fd64 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Tue, 31 Jul 2018 10:27:51 -0700 Subject: [PATCH 54/59] add memory note, mention libFuzzer early --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3b884b4..767ce0b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The [2018 IEEE Cybersecurity Development Conference](https://secdev.ieee.org/201 * Tests look like Google Test, but can use symbolic execution/fuzzing to generate data (parameterized unit testing) * Easier to learn than binary analysis tools/fuzzers, but provides similar functionality -* Already supports Manticore, Angr, Dr. Fuzz, file-based fuzzing with e.g., AFL; more back-ends likely in future +* Already supports Manticore, Angr, libFuzzer, file-based fuzzing with e.g., AFL; more back-ends likely in future * Switch test generation tool without re-writing test harness * Work around show-stopper bugs * Find out which tool works best for your code under test @@ -46,7 +46,7 @@ Runtime: ## Building on Ubuntu 16.04 (Xenial) -```shell +AFL```shell sudo apt update && sudo apt-get install build-essential gcc-multilib g++-multilib cmake python python-setuptools libffi-dev z3 git clone https://github.com/trailofbits/deepstate deepstate mkdir deepstate/build && cd deepstate/build @@ -109,7 +109,13 @@ mkdir OneOf_corpus Use the `LIBFUZZER_WHICH_TEST` environment variable to control which test libFuzzer runs, using a -fully qualified name (e.g., `Arithmetic_InvertibleMultiplication_CanFail`). +fully qualified name (e.g., +`Arithmetic_InvertibleMultiplication_CanFail`). + +One hint when using libFuzzer is to avoid dynamically allocating +memory during a test, if that memory would not be freed on a test +failure. This will leak memory and libFuzzer will run out of memory +very quickly in each fuzzing session. ## Fuzzing with AFL From 9d5bba2d8278f0316cde7ea77bf4c14436fabc28 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Wed, 1 Aug 2018 12:34:45 -0700 Subject: [PATCH 55/59] for now, ignore this test on manticore --- tests/test_lists.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_lists.py b/tests/test_lists.py index 5c8107c..2c0b9db 100644 --- a/tests/test_lists.py +++ b/tests/test_lists.py @@ -5,6 +5,8 @@ import deepstate_base class ListsTest(deepstate_base.DeepStateTestCase): def run_deepstate(self, deepstate): + if deepstate == "deepstate-manticore": + return # Just skip for now, we know it's too slow (r, output) = logrun.logrun([deepstate, "build/examples/Lists"], "deepstate.out", 3000) self.assertEqual(r, 0) From ffdd449f07a95ba059f7dd165b5f82dba983794e Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 3 Aug 2018 09:56:38 -0700 Subject: [PATCH 56/59] make changes requested, fix cut/paste error, etc. --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 767ce0b..d4b0f03 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Runtime: ## Building on Ubuntu 16.04 (Xenial) -AFL```shell +```shell sudo apt update && sudo apt-get install build-essential gcc-multilib g++-multilib cmake python python-setuptools libffi-dev z3 git clone https://github.com/trailofbits/deepstate deepstate mkdir deepstate/build && cd deepstate/build @@ -91,15 +91,16 @@ DeepState consists of a static library, used to write test harnesses, and comman ## Fuzzing with libFuzzer -If you install a recent-enough clang, and run `cmake` when you install -with `BUILD_LIBFUZZER` defined, you can generate tests using LlibFuzzer. -Because both DeepState and libFuzzer want to be `main`, this requires -building a different executable for libFuzzer. The `examples` -directory shows how this can be done. The libFuzzer executable works -like any other libFuzzer executable, and the tests produced can be run -using the normal DeepState executable. For example, generating some -tests of the `OneOf` example (up to 5,000 runs), then running those -tests to examine the results, would look like: +If you install clang 6.0 or later, and run `cmake` when you install +with the `BUILD_LIBFUZZER` environment variable defined, you can +generate tests using LlibFuzzer. Because both DeepState and libFuzzer +want to be `main`, this requires building a different executable for +libFuzzer. The `examples` directory shows how this can be done. The +libFuzzer executable works like any other libFuzzer executable, and +the tests produced can be run using the normal DeepState executable. +For example, generating some tests of the `OneOf` example (up to 5,000 +runs), then running those tests to examine the results, would look +like: ```shell mkdir OneOf_corpus From 0939f945264778f60ac2678c8fc4313d381f1862 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 3 Aug 2018 10:20:40 -0700 Subject: [PATCH 57/59] fix README on review --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d4b0f03..352b55d 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,8 @@ runs), then running those tests to examine the results, would look like: ```shell -mkdir OneOf_corpus -./OneOf_LF OneOf_libFuzzer_corpus --runs 5000 +mkdir OneOf_libFuzzer_corpus +./OneOf_LF OneOf_libFuzzer_corpus -runs 5000 ./OneOf --input_test_files_dir OneOf_libFuzzer_corpus ``` From 1e35f318c68f4d2f744b7980e3f8fa1ac0363e17 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 3 Aug 2018 10:30:00 -0700 Subject: [PATCH 58/59] clarify libfuzzer --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 352b55d..e53a702 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,10 @@ mkdir OneOf_libFuzzer_corpus Use the `LIBFUZZER_WHICH_TEST` environment variable to control which test libFuzzer runs, using a fully qualified name (e.g., -`Arithmetic_InvertibleMultiplication_CanFail`). +`Arithmetic_InvertibleMultiplication_CanFail`). By default, you get +the last test defined (which works fine if there is only one test). +Obviously, libFuzzer may work better if you provide a non-empty +corpus, but fuzzing will work even without an initial corpus, unlike AFL. One hint when using libFuzzer is to avoid dynamically allocating memory during a test, if that memory would not be freed on a test From 01ae7094669a2b3e9ad4f70be1257100cceb6bf5 Mon Sep 17 00:00:00 2001 From: Alex Groce Date: Fri, 3 Aug 2018 11:40:36 -0700 Subject: [PATCH 59/59] fix command line args for libfuzzer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e53a702..7ffaa43 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ like: ```shell mkdir OneOf_libFuzzer_corpus -./OneOf_LF OneOf_libFuzzer_corpus -runs 5000 +./OneOf_LF -runs=5000 OneOf_libFuzzer_corpus ./OneOf --input_test_files_dir OneOf_libFuzzer_corpus ```