Index: lib/Fuzzer/afl/afl_driver.cpp =================================================================== --- lib/Fuzzer/afl/afl_driver.cpp +++ lib/Fuzzer/afl/afl_driver.cpp @@ -60,6 +60,21 @@ static const size_t kMaxAflInputSize = 1 << 20; static uint8_t AflInputBuf[kMaxAflInputSize]; +// If the user asks us to duplicate stderr, then do it. +void duplicate_stderr() { + char* stderr_duplicate_filename = + getenv("AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); + + if (!stderr_duplicate_filename) + return; + + FILE* stderr_duplicate_stream = + freopen(stderr_duplicate_filename, "a+", stderr); + + assert(stderr_duplicate_stream && + "Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME"); +} + int main(int argc, char **argv) { fprintf(stderr, "Running in AFl-fuzz mode\nUsage:\n" "afl-fuzz [afl-flags] %s [N] " @@ -70,6 +85,8 @@ LLVMFuzzerInitialize(&argc, &argv); // Do any other expensive one-time initialization here. + duplicate_stderr(); + __afl_manual_init(); int N = 1000; Index: lib/Fuzzer/test/AFLDriverTest.cpp =================================================================== --- /dev/null +++ lib/Fuzzer/test/AFLDriverTest.cpp @@ -0,0 +1,12 @@ +#include +#include + +extern "C" void __afl_manual_init() {} + +extern "C" int __afl_persistent_loop(unsigned int) { + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + return 0; +} Index: lib/Fuzzer/test/CMakeLists.txt =================================================================== --- lib/Fuzzer/test/CMakeLists.txt +++ lib/Fuzzer/test/CMakeLists.txt @@ -110,6 +110,19 @@ endforeach() ############################################################################### +# AFL Driver test +############################################################################### + +add_executable(AFLDriverTest + AFLDriverTest.cpp ../afl/afl_driver.cpp) + +set_target_properties(AFLDriverTest + PROPERTIES RUNTIME_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" + ) +set(TestBinaries ${TestBinaries} AFLDriverTest) + +############################################################################### # Unit tests ############################################################################### Index: lib/Fuzzer/test/afl-driver.test =================================================================== --- /dev/null +++ lib/Fuzzer/test/afl-driver.test @@ -0,0 +1,11 @@ +; Test that not specifying a file isn't broken. +RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME +RUN: AFLDriverTest + +; Test that specifying an invalid file causes a crash. +RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME="%T" not --crash AFLDriverTest + +; Test that a file is created when specified as the duplicate stderr. +RUN: AFL_DRIVER_STDERR_DUPLICATE_FILENAME=%t AFLDriverTest +RUN: stat %t +RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME