diff options
Diffstat (limited to 'lib/Fuzzer/test')
63 files changed, 649 insertions, 165 deletions
diff --git a/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp b/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp index 577481431ae2..69b0d59fb8ef 100644 --- a/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp +++ b/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp @@ -14,7 +14,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { uint64_t y; memcpy(&x, Data, sizeof(x)); memcpy(&y, Data + sizeof(x), sizeof(y)); - if (labs(x) < 0 && y == 0xbaddcafedeadbeefUL) { + if (llabs(x) < 0 && y == 0xbaddcafedeadbeefULL) { printf("BINGO; Found the target, exiting; x = 0x%lx y 0x%lx\n", x, y); exit(1); } diff --git a/lib/Fuzzer/test/BadStrcmpTest.cpp b/lib/Fuzzer/test/BadStrcmpTest.cpp new file mode 100644 index 000000000000..159cd7ea5f70 --- /dev/null +++ b/lib/Fuzzer/test/BadStrcmpTest.cpp @@ -0,0 +1,19 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Test that we don't creash in case of bad strcmp params. +#include <cstdint> +#include <cstring> +#include <cstddef> + +static volatile int Sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size != 10) return 0; + // Data is not zero-terminated, so this call is bad. + // Still, there are cases when such calles appear, see e.g. + // https://bugs.llvm.org/show_bug.cgi?id=32357 + Sink = strcmp(reinterpret_cast<const char*>(Data), "123456789"); + return 0; +} + diff --git a/lib/Fuzzer/test/BogusInitializeTest.cpp b/lib/Fuzzer/test/BogusInitializeTest.cpp new file mode 100644 index 000000000000..c7e81a5478b2 --- /dev/null +++ b/lib/Fuzzer/test/BogusInitializeTest.cpp @@ -0,0 +1,15 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Make sure LLVMFuzzerInitialize does not change argv[0]. +#include <stddef.h> +#include <stdint.h> + +extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { + ***argv = 'X'; + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + return 0; +} diff --git a/lib/Fuzzer/test/CMakeLists.txt b/lib/Fuzzer/test/CMakeLists.txt index c0457746a0e7..f72bc3909a3c 100644 --- a/lib/Fuzzer/test/CMakeLists.txt +++ b/lib/Fuzzer/test/CMakeLists.txt @@ -11,21 +11,35 @@ set(variables_to_filter LIBFUZZER_FLAGS_BASE ) foreach (VARNAME ${variables_to_filter}) - string(REPLACE " " ";" BUILD_FLAGS_AS_LIST "${${VARNAME}}") - set(new_flags "") - foreach (flag ${BUILD_FLAGS_AS_LIST}) - # NOTE: Use of XX here is to avoid a CMake warning due to CMP0054 - if (NOT ("XX${flag}" MATCHES "XX-O[0123s]")) - set(new_flags "${new_flags} ${flag}") - else() - set(new_flags "${new_flags} -O0") - endif() - endforeach() - set(${VARNAME} "${new_flags}") + string(REGEX REPLACE "([-/]O)[123s]" "\\10" ${VARNAME} "${${VARNAME}}") endforeach() # Enable the coverage instrumentation (it is disabled for the Fuzzer lib). -set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp,trace-div,trace-gep -g") +set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp,trace-div,trace-gep -gline-tables-only") + +if(MSVC) + # For tests use the CRT specified for release build + # (asan doesn't support MDd and MTd) + if ("${LLVM_USE_CRT_RELEASE}" STREQUAL "") + set(CRT_FLAG " /MD ") + else() + set(CRT_FLAG " /${LLVM_USE_CRT_RELEASE} ") + endif() + # In order to use the sanitizers in Windows, we need to link against many + # runtime libraries which will depend on the target being created + # (executable or dll) and the c runtime library used (MT/MD). + # By default, cmake uses link.exe for linking, which fails because we don't + # specify the appropiate dependencies. + # As we don't want to consider all of that possible situations which depends + # on the implementation of the compiler-rt, the simplest option is to change + # the rules for linking executables and shared libraries, using the compiler + # instead of link.exe. Clang will consider the sanitizer flags, and + # automatically provide the required libraries to the linker. + set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> ${CMAKE_CXX_FLAGS} ${CRT_FLAG} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> /link <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS>") + set(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> ${CMAKE_CXX_FLAGS} ${CRT_FLAG} /LD <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG> <TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> /link <LINK_FLAGS>") +endif() + +add_custom_target(TestBinaries) # add_libfuzzer_test(<name> # SOURCES source0.cpp [source1.cpp ...] @@ -51,12 +65,9 @@ function(add_libfuzzer_test name) PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" ) - set(TestBinaries ${TestBinaries} LLVMFuzzer-${name} PARENT_SCOPE) + add_dependencies(TestBinaries LLVMFuzzer-${name}) endfunction() -# Variable to keep track of all test targets -set(TestBinaries) - ############################################################################### # Basic tests ############################################################################### @@ -65,16 +76,23 @@ set(Tests AbsNegAndConstantTest AbsNegAndConstant64Test AccumulateAllocationsTest + BadStrcmpTest + BogusInitializeTest BufferOverflowOnInput CallerCalleeTest CounterTest + CustomCrossOverAndMutateTest CustomCrossOverTest CustomMutatorTest + CxxStringEqTest DivTest EmptyTest + EquivalenceATest + EquivalenceBTest FourIndependentBranchesTest FullCoverageSetTest InitializeTest + Memcmp64BytesTest MemcmpTest LeakTest LeakTimeoutTest @@ -92,6 +110,7 @@ set(Tests SimpleHashTest SimpleTest SimpleThreadedTest + SingleByteInputTest SingleMemcmpTest SingleStrcmpTest SingleStrncmpTest @@ -105,17 +124,19 @@ set(Tests SwapCmpTest SwitchTest Switch2Test + TableLookupTest ThreadedLeakTest ThreadedTest TimeoutTest TimeoutEmptyTest TraceMallocTest + TwoDifferentBugsTest ) -if(APPLE) - # LeakSanitizer is not supported on OSX right now +if(APPLE OR MSVC) + # LeakSanitizer is not supported on OSX and Windows right now set(HAS_LSAN 0) - message(WARNING "LeakSanitizer is not supported on Apple platforms." + message(WARNING "LeakSanitizer is not supported." " Building and running LibFuzzer LeakSanitizer tests is disabled." ) else() @@ -126,6 +147,17 @@ foreach(Test ${Tests}) add_libfuzzer_test(${Test} SOURCES ${Test}.cpp) endforeach() +function(test_export_symbol target symbol) + if(MSVC) + set_target_properties(LLVMFuzzer-${target} PROPERTIES LINK_FLAGS + "-export:${symbol}") + endif() +endfunction() + +test_export_symbol(InitializeTest "LLVMFuzzerInitialize") +test_export_symbol(BogusInitializeTest "LLVMFuzzerInitialize") +test_export_symbol(CustomCrossOverTest "LLVMFuzzerCustomCrossOver") +test_export_symbol(CustomMutatorTest "LLVMFuzzerCustomMutator") ############################################################################### # Unit tests @@ -150,13 +182,13 @@ target_include_directories(LLVMFuzzer-Unittest PRIVATE "${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include" ) -set(TestBinaries ${TestBinaries} LLVMFuzzer-Unittest) +add_dependencies(TestBinaries LLVMFuzzer-Unittest) set_target_properties(LLVMFuzzer-Unittest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) -set(TestBinaries ${TestBinaries} LLVMFuzzer-StandaloneInitializeTest) +add_dependencies(TestBinaries LLVMFuzzer-StandaloneInitializeTest) set_target_properties(LLVMFuzzer-StandaloneInitializeTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" @@ -170,6 +202,7 @@ include_directories(..) # add_subdirectory(uninstrumented) add_subdirectory(no-coverage) +add_subdirectory(trace-pc) add_subdirectory(ubsan) add_library(LLVMFuzzer-DSO1 SHARED DSO1.cpp) @@ -187,12 +220,22 @@ target_link_libraries(LLVMFuzzer-DSOTest set_target_properties(LLVMFuzzer-DSOTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/Fuzzer/test") -set_target_properties(LLVMFuzzer-DSO1 PROPERTIES LIBRARY_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib") -set_target_properties(LLVMFuzzer-DSO2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib") -set(TestBinaries ${TestBinaries} LLVMFuzzer-DSOTest) +if(MSVC) + set_output_directory(LLVMFuzzer-DSO1 + BINARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" + LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test") + set_output_directory(LLVMFuzzer-DSO2 + BINARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" + LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test") +else(MSVC) + set_output_directory(LLVMFuzzer-DSO1 + LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib") + set_output_directory(LLVMFuzzer-DSO2 + LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib") +endif() + +add_dependencies(TestBinaries LLVMFuzzer-DSOTest) ############################################################################### # Configure lit to run the tests @@ -200,6 +243,10 @@ set(TestBinaries ${TestBinaries} LLVMFuzzer-DSOTest) # Note this is done after declaring all tests so we can inform lit if any tests # need to be disabled. ############################################################################### +set(LIBFUZZER_POSIX 1) +if (MSVC) + set(LIBFUZZER_POSIX 0) +endif() configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in @@ -213,5 +260,11 @@ configure_lit_site_cfg( add_lit_testsuite(check-fuzzer "Running Fuzzer tests" ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${TestBinaries} FileCheck not + DEPENDS TestBinaries ) + +# Don't add dependencies on Windows. The linker step would fail on Windows, +# since cmake will use link.exe for linking and won't include compiler-rt libs. +if(NOT MSVC) + add_dependencies(check-fuzzer FileCheck sancov not) +endif() diff --git a/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp b/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp new file mode 100644 index 000000000000..74fc939534ca --- /dev/null +++ b/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp @@ -0,0 +1,34 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Test that libFuzzer does not crash when LLVMFuzzerMutate called from +// LLVMFuzzerCustomCrossOver. +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstdlib> +#include <string.h> +#include <string> +#include <vector> + +#include "FuzzerInterface.h" + +static volatile int sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + std::string Str(reinterpret_cast<const char *>(Data), Size); + if (Size && Data[0] == '0') + sink++; + return 0; +} + +extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, + const uint8_t *Data2, size_t Size2, + uint8_t *Out, size_t MaxOutSize, + unsigned int Seed) { + std::vector<uint8_t> Buffer(MaxOutSize * 10); + LLVMFuzzerMutate(Buffer.data(), Buffer.size(), Buffer.size()); + size_t Size = std::min(Size1, MaxOutSize); + memcpy(Out, Data1, Size); + return Size; +} diff --git a/lib/Fuzzer/test/CxxStringEqTest.cpp b/lib/Fuzzer/test/CxxStringEqTest.cpp new file mode 100644 index 000000000000..e0e23c972ccb --- /dev/null +++ b/lib/Fuzzer/test/CxxStringEqTest.cpp @@ -0,0 +1,25 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Simple test for a fuzzer. Must find a specific string +// used in std::string operator ==. +#include <cstdint> +#include <cstdlib> +#include <cstddef> +#include <string> +#include <iostream> + +static volatile int Sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + std::string Str((const char*)Data, Size); + bool Eq = Str == "FooBar"; + Sink = Str == "123456"; // Try to confuse the fuzzer + if (Eq) { + std::cout << "BINGO; Found the target, exiting\n"; + std::cout.flush(); + abort(); + } + return 0; +} + diff --git a/lib/Fuzzer/test/DSO1.cpp b/lib/Fuzzer/test/DSO1.cpp index 4a293890f4b0..72a5ec4a0cde 100644 --- a/lib/Fuzzer/test/DSO1.cpp +++ b/lib/Fuzzer/test/DSO1.cpp @@ -2,7 +2,9 @@ // License. See LICENSE.TXT for details. // Source code for a simple DSO. - +#ifdef _WIN32 +__declspec( dllexport ) +#endif int DSO1(int a) { if (a < 123456) return 0; diff --git a/lib/Fuzzer/test/DSO2.cpp b/lib/Fuzzer/test/DSO2.cpp index 04b308d193ac..2967055dc227 100644 --- a/lib/Fuzzer/test/DSO2.cpp +++ b/lib/Fuzzer/test/DSO2.cpp @@ -2,7 +2,9 @@ // License. See LICENSE.TXT for details. // Source code for a simple DSO. - +#ifdef _WIN32 +__declspec( dllexport ) +#endif int DSO2(int a) { if (a < 3598235) return 0; diff --git a/lib/Fuzzer/test/EquivalenceATest.cpp b/lib/Fuzzer/test/EquivalenceATest.cpp new file mode 100644 index 000000000000..7d1ebb0f6a4a --- /dev/null +++ b/lib/Fuzzer/test/EquivalenceATest.cpp @@ -0,0 +1,17 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +// Test for libFuzzer's "equivalence" fuzzing, part A. +extern "C" void LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + // fprintf(stderr, "A %zd\n", Size); + uint8_t Result[50]; + if (Size > 50) Size = 50; + for (size_t i = 0; i < Size; i++) + Result[Size - i - 1] = Data[i]; + LLVMFuzzerAnnounceOutput(Result, Size); + return 0; +} diff --git a/lib/Fuzzer/test/EquivalenceBTest.cpp b/lib/Fuzzer/test/EquivalenceBTest.cpp new file mode 100644 index 000000000000..b1de208b57f6 --- /dev/null +++ b/lib/Fuzzer/test/EquivalenceBTest.cpp @@ -0,0 +1,27 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +// Test for libFuzzer's "equivalence" fuzzing, part B. +extern "C" void LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + // fprintf(stderr, "B %zd\n", Size); + uint8_t Result[50]; + if (Size > 50) Size = 50; + for (size_t i = 0; i < Size; i++) + Result[Size - i - 1] = Data[i]; + + // Be a bit different from EquivalenceATest + if (Size > 10 && Data[5] == 'B' && Data[6] == 'C' && Data[7] == 'D') { + static int c; + if (!c) + fprintf(stderr, "ZZZZZZZ\n"); + c = 1; + Result[2]++; + } + + LLVMFuzzerAnnounceOutput(Result, Size); + return 0; +} diff --git a/lib/Fuzzer/test/FuzzerUnittest.cpp b/lib/Fuzzer/test/FuzzerUnittest.cpp index 4992ef57b6ca..78ea874f2ce2 100644 --- a/lib/Fuzzer/test/FuzzerUnittest.cpp +++ b/lib/Fuzzer/test/FuzzerUnittest.cpp @@ -10,10 +10,12 @@ #include "FuzzerDictionary.h" #include "FuzzerMerge.h" #include "FuzzerMutate.h" +#include "FuzzerTracePC.h" #include "FuzzerRandom.h" #include "gtest/gtest.h" #include <memory> #include <set> +#include <sstream> using namespace fuzzer; @@ -584,15 +586,15 @@ TEST(FuzzerUtil, Base64) { TEST(Corpus, Distribution) { Random Rand(0); - InputCorpus C(""); + std::unique_ptr<InputCorpus> C(new InputCorpus("")); size_t N = 10; size_t TriesPerUnit = 1<<16; for (size_t i = 0; i < N; i++) - C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 0); + C->AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 0); std::vector<size_t> Hist(N); for (size_t i = 0; i < N * TriesPerUnit; i++) { - Hist[C.ChooseUnitIdxToMutate(Rand)]++; + Hist[C->ChooseUnitIdxToMutate(Rand)]++; } for (size_t i = 0; i < N; i++) { // A weak sanity check that every unit gets invoked. @@ -636,7 +638,10 @@ static void Merge(const std::string &Input, Merger M; std::vector<std::string> NewFiles; EXPECT_TRUE(M.Parse(Input, true)); + std::stringstream SS; + M.PrintSummary(SS); EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles)); + EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS)); EQ(NewFiles, Result); } @@ -706,6 +711,16 @@ TEST(Merge, Good) { EQ(M.Files[2].Features, {1, 3, 6}); EXPECT_EQ(3U, M.Merge(&NewFiles)); EQ(NewFiles, {"B"}); + + // Same as the above, but with InitialFeatures. + EXPECT_TRUE(M.Parse("2\n0\nB\nC\n" + "STARTED 0 1001\nDONE 0 4 5 6 \n" + "STARTED 1 1002\nDONE 1 6 1 3\n" + "", true)); + EQ(M.Files[0].Features, {4, 5, 6}); + EQ(M.Files[1].Features, {1, 3, 6}); + EXPECT_EQ(3U, M.Merge({1, 2, 3}, &NewFiles)); + EQ(NewFiles, {"B"}); } TEST(Merge, Merge) { @@ -736,3 +751,25 @@ TEST(Merge, Merge) { "STARTED 3 1000\nDONE 3 1 \n", {"B", "D"}, 3); } + +TEST(Fuzzer, ForEachNonZeroByte) { + const size_t N = 64; + alignas(64) uint8_t Ar[N + 8] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + }; + typedef std::vector<std::pair<size_t, uint8_t> > Vec; + Vec Res, Expected; + auto CB = [&](size_t Idx, uint8_t V) { Res.push_back({Idx, V}); }; + ForEachNonZeroByte(Ar, Ar + N, 100, CB); + Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4}, + {135, 5}, {137, 6}, {146, 7}, {163, 8}}; + EXPECT_EQ(Res, Expected); +} diff --git a/lib/Fuzzer/test/LargeTest.cpp b/lib/Fuzzer/test/LargeTest.cpp new file mode 100644 index 000000000000..83ed61971801 --- /dev/null +++ b/lib/Fuzzer/test/LargeTest.cpp @@ -0,0 +1,37 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// A fuzz target with lots of edges. +#include <cstdint> +#include <cstdlib> + +static inline void break_optimization(const void *arg) { + __asm__ __volatile__("" : : "r" (arg) : "memory"); +} + +#define A \ + do { \ + i++; \ + c++; \ + if (Data[(i + __LINE__) % Size] == (c % 256)) \ + break_optimization(Data); \ + else \ + break_optimization(0); \ + } while (0) + +// for (int i = 0, n = Data[(__LINE__ - 1) % Size] % 16; i < n; i++) + +#define B do{A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; }while(0) +#define C do{B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; }while(0) +#define D do{C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; }while(0) +#define E do{D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; }while(0) + +volatile int sink; +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (!Size) return 0; + int c = 0; + int i = 0; + D; + return 0; +} + diff --git a/lib/Fuzzer/test/LoadTest.cpp b/lib/Fuzzer/test/LoadTest.cpp index c1780d5c7bd9..eef16c7be51e 100644 --- a/lib/Fuzzer/test/LoadTest.cpp +++ b/lib/Fuzzer/test/LoadTest.cpp @@ -14,7 +14,7 @@ int array[kArraySize]; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size < 8) return 0; - size_t a = 0; + uint64_t a = 0; memcpy(&a, Data, 8); Sink = array[a % (kArraySize + 1)]; return 0; diff --git a/lib/Fuzzer/test/Memcmp64BytesTest.cpp b/lib/Fuzzer/test/Memcmp64BytesTest.cpp new file mode 100644 index 000000000000..e81526b578a3 --- /dev/null +++ b/lib/Fuzzer/test/Memcmp64BytesTest.cpp @@ -0,0 +1,20 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Simple test for a fuzzer. The fuzzer must find a particular string. +#include <cassert> +#include <cstring> +#include <cstdint> +#include <cstdio> +#include <cstdlib> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + const char kString64Bytes[] = + "123456789 123456789 123456789 123456789 123456789 123456789 1234"; + assert(sizeof(kString64Bytes) == 65); + if (Size >= 64 && memcmp(Data, kString64Bytes, 64) == 0) { + fprintf(stderr, "BINGO\n"); + exit(1); + } + return 0; +} diff --git a/lib/Fuzzer/test/UninstrumentedTest.cpp b/lib/Fuzzer/test/NotinstrumentedTest.cpp index ffe952c749d2..ffe952c749d2 100644 --- a/lib/Fuzzer/test/UninstrumentedTest.cpp +++ b/lib/Fuzzer/test/NotinstrumentedTest.cpp diff --git a/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp b/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp index ea23a601aa23..316b7682b8e6 100644 --- a/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp +++ b/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp @@ -15,7 +15,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size > 0 && Data[0] == 'H') { if (Size > 1 && Data[1] == 'i') { if (Size > 2 && Data[2] == '!') { - size_t kSize = 0xff000000U; + size_t kSize = 0x20000000U; char *p = new char[kSize]; SinkPtr = p; delete [] p; diff --git a/lib/Fuzzer/test/RepeatedMemcmp.cpp b/lib/Fuzzer/test/RepeatedMemcmp.cpp index a327bbee7815..7377f65ed76d 100644 --- a/lib/Fuzzer/test/RepeatedMemcmp.cpp +++ b/lib/Fuzzer/test/RepeatedMemcmp.cpp @@ -8,13 +8,16 @@ #include <cstdlib> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - int Matches = 0; - for (size_t i = 0; i + 2 < Size; i += 3) { - const char *Pat = i % 2 ? "foo" : "bar"; - if (!memcmp(Data + i, Pat, 3)) - Matches++; - } - if (Matches > 20) { + int Matches1 = 0; + for (size_t i = 0; i + 2 < Size; i += 3) + if (!memcmp(Data + i, "foo", 3)) + Matches1++; + int Matches2 = 0; + for (size_t i = 0; i + 2 < Size; i += 3) + if (!memcmp(Data + i, "bar", 3)) + Matches2++; + + if (Matches1 > 10 && Matches2 > 10) { fprintf(stderr, "BINGO!\n"); exit(1); } diff --git a/lib/Fuzzer/test/SimpleCmpTest.cpp b/lib/Fuzzer/test/SimpleCmpTest.cpp index 0220c30f9a6b..12b5cdda0660 100644 --- a/lib/Fuzzer/test/SimpleCmpTest.cpp +++ b/lib/Fuzzer/test/SimpleCmpTest.cpp @@ -26,12 +26,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { memcpy(&y, Data + 8, 8); // 16 memcpy(&z, Data + 16, sizeof(z)); // 20 memcpy(&a, Data + 20, sizeof(a)); // 22 + const bool k32bit = sizeof(void*) == 4; - if (x > 1234567890 && PrintOnce(__LINE__) && - x < 1234567895 && PrintOnce(__LINE__) && + if ((k32bit || x > 1234567890) && PrintOnce(__LINE__) && + (k32bit || x < 1234567895) && PrintOnce(__LINE__) && a == 0x4242 && PrintOnce(__LINE__) && - y >= 987654321 && PrintOnce(__LINE__) && - y <= 987654325 && PrintOnce(__LINE__) && + (k32bit || y >= 987654321) && PrintOnce(__LINE__) && + (k32bit || y <= 987654325) && PrintOnce(__LINE__) && z < -10000 && PrintOnce(__LINE__) && z >= -10005 && PrintOnce(__LINE__) && z != -10003 && PrintOnce(__LINE__) && diff --git a/lib/Fuzzer/test/SingleByteInputTest.cpp b/lib/Fuzzer/test/SingleByteInputTest.cpp new file mode 100644 index 000000000000..4ce819d230ce --- /dev/null +++ b/lib/Fuzzer/test/SingleByteInputTest.cpp @@ -0,0 +1,17 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Simple test for a fuzzer, need just one byte to crash. +#include <cstdint> +#include <cstdlib> +#include <cstddef> +#include <cstdio> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size > 0 && Data[Size/2] == 42) { + fprintf(stderr, "BINGO\n"); + abort(); + } + return 0; +} + diff --git a/lib/Fuzzer/test/SingleStrcmpTest.cpp b/lib/Fuzzer/test/SingleStrcmpTest.cpp index 73470b527eeb..48f481dfc51a 100644 --- a/lib/Fuzzer/test/SingleStrcmpTest.cpp +++ b/lib/Fuzzer/test/SingleStrcmpTest.cpp @@ -8,10 +8,14 @@ #include <cstdlib> extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - char *S = (char*)Data; - if (Size >= 7 && !strcmp(S, "qwerty")) { - fprintf(stderr, "BINGO\n"); - exit(1); + if (Size >= 7) { + char Copy[7]; + memcpy(Copy, Data, 6); + Copy[6] = 0; + if (!strcmp(Copy, "qwerty")) { + fprintf(stderr, "BINGO\n"); + exit(1); + } } return 0; } diff --git a/lib/Fuzzer/test/SingleStrncmpTest.cpp b/lib/Fuzzer/test/SingleStrncmpTest.cpp index dbcc464b0a78..e5601da86329 100644 --- a/lib/Fuzzer/test/SingleStrncmpTest.cpp +++ b/lib/Fuzzer/test/SingleStrncmpTest.cpp @@ -9,7 +9,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { char *S = (char*)Data; - if (Size >= 6 && !strncmp(S, "qwerty", 6)) { + volatile auto Strncmp = &(strncmp); // Make sure strncmp is not inlined. + if (Size >= 6 && !Strncmp(S, "qwerty", 6)) { fprintf(stderr, "BINGO\n"); exit(1); } diff --git a/lib/Fuzzer/test/SwapCmpTest.cpp b/lib/Fuzzer/test/SwapCmpTest.cpp index f79db4ccf714..b90ac72c22c4 100644 --- a/lib/Fuzzer/test/SwapCmpTest.cpp +++ b/lib/Fuzzer/test/SwapCmpTest.cpp @@ -19,8 +19,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { x = __builtin_bswap64(x); y = __builtin_bswap32(y); z = __builtin_bswap16(z); + const bool k32bit = sizeof(void*) == 4; - if (x == 0x46555A5A5A5A5546ULL && + if ((k32bit || x == 0x46555A5A5A5A5546ULL) && z == 0x4F4B && y == 0x66757A7A && true diff --git a/lib/Fuzzer/test/TableLookupTest.cpp b/lib/Fuzzer/test/TableLookupTest.cpp new file mode 100644 index 000000000000..f9d5610820ff --- /dev/null +++ b/lib/Fuzzer/test/TableLookupTest.cpp @@ -0,0 +1,45 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Make sure the fuzzer eventually finds all possible values of a variable +// within a range. +#include <cstring> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cassert> +#include <set> + +const size_t N = 1 << 12; + +// Define an array of counters that will be understood by libFuzzer +// as extra coverage signal. The array must be: +// * uint8_t +// * aligned by 64 +// * in the section named __libfuzzer_extra_counters. +// The target code may declare more than one such array. +// +// Use either `Counters[Idx] = 1` or `Counters[Idx]++;` +// depending on whether multiple occurrences of the event 'Idx' +// is important to distinguish from one occurrence. +#ifdef __linux__ +alignas(64) __attribute__((section("__libfuzzer_extra_counters"))) +#endif +static uint8_t Counters[N]; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + static std::set<uint16_t> SeenIdx; + if (Size != 4) return 0; + uint32_t Idx; + memcpy(&Idx, Data, 4); + Idx %= N; + assert(Counters[Idx] == 0); // libFuzzer should reset these between the runs. + // Or Counters[Idx]=1 if we don't care how many times this happened. + Counters[Idx]++; + SeenIdx.insert(Idx); + if (SeenIdx.size() == N) { + fprintf(stderr, "BINGO: found all values\n"); + abort(); + } + return 0; +} diff --git a/lib/Fuzzer/test/TwoDifferentBugsTest.cpp b/lib/Fuzzer/test/TwoDifferentBugsTest.cpp new file mode 100644 index 000000000000..42c0d192ba86 --- /dev/null +++ b/lib/Fuzzer/test/TwoDifferentBugsTest.cpp @@ -0,0 +1,22 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Simple test for a fuzzer. This test may trigger two different bugs. +#include <cstdint> +#include <cstdlib> +#include <cstddef> +#include <iostream> + +static volatile int *Null = 0; + +void Foo() { Null[1] = 0; } +void Bar() { Null[2] = 0; } + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (Size < 10 && Data[0] == 'H') + Foo(); + if (Size >= 10 && Data[0] == 'H') + Bar(); + return 0; +} + diff --git a/lib/Fuzzer/test/afl-driver-extra-stats.test b/lib/Fuzzer/test/afl-driver-extra-stats.test index 81e384e7dad2..1b0818e55ea5 100644 --- a/lib/Fuzzer/test/afl-driver-extra-stats.test +++ b/lib/Fuzzer/test/afl-driver-extra-stats.test @@ -1,3 +1,5 @@ +REQUIRES: posix + ; Test that not specifying an extra stats file isn't broken. RUN: unset AFL_DRIVER_EXTRA_STATS_FILENAME RUN: AFLDriverTest diff --git a/lib/Fuzzer/test/afl-driver-stderr.test b/lib/Fuzzer/test/afl-driver-stderr.test index c0f9c8398c2a..e835acd4275b 100644 --- a/lib/Fuzzer/test/afl-driver-stderr.test +++ b/lib/Fuzzer/test/afl-driver-stderr.test @@ -1,3 +1,5 @@ +REQUIRES: posix + ; Test that not specifying a stderr file isn't broken. RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME RUN: AFLDriverTest diff --git a/lib/Fuzzer/test/bad-strcmp.test b/lib/Fuzzer/test/bad-strcmp.test new file mode 100644 index 000000000000..9a2f3742a5f4 --- /dev/null +++ b/lib/Fuzzer/test/bad-strcmp.test @@ -0,0 +1 @@ +RUN: LLVMFuzzer-BadStrcmpTest -runs=100000 diff --git a/lib/Fuzzer/test/coverage.test b/lib/Fuzzer/test/coverage.test index fa11be502ef9..ff3fdff57a3d 100644 --- a/lib/Fuzzer/test/coverage.test +++ b/lib/Fuzzer/test/coverage.test @@ -1,9 +1,11 @@ +XFAIL: darwin + CHECK: COVERAGE: CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13 CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14 CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16 CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:19 -CHECK: COVERED_DIRS: {{.*}}lib/Fuzzer/test +CHECK: COVERED_DIRS: {{.*}}lib{{[/\\]}}Fuzzer{{[/\\]}}test RUN: not LLVMFuzzer-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s RUN: LLVMFuzzer-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO diff --git a/lib/Fuzzer/test/cxxstring.test b/lib/Fuzzer/test/cxxstring.test new file mode 100644 index 000000000000..c60d7aee9686 --- /dev/null +++ b/lib/Fuzzer/test/cxxstring.test @@ -0,0 +1,2 @@ +RUN: not LLVMFuzzer-CxxStringEqTest -seed=1 -runs=1000000 2>&1 | FileCheck %s +CHECK: BINGO diff --git a/lib/Fuzzer/test/disable-leaks.test b/lib/Fuzzer/test/disable-leaks.test new file mode 100644 index 000000000000..467b64ccc6f4 --- /dev/null +++ b/lib/Fuzzer/test/disable-leaks.test @@ -0,0 +1,4 @@ +REQUIRES: lsan +RUN: LLVMFuzzer-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS +ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation + diff --git a/lib/Fuzzer/test/dump_coverage.test b/lib/Fuzzer/test/dump_coverage.test index 9bd98daa3619..8acc8304fc60 100644 --- a/lib/Fuzzer/test/dump_coverage.test +++ b/lib/Fuzzer/test/dump_coverage.test @@ -1,16 +1,14 @@ -RUN: DIR=%t_workdir -RUN: BUILD_DIR=$(pwd) -RUN: rm -rf $DIR && mkdir -p $DIR && cd $DIR -RUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s -RUN: $BUILD_DIR/LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO -RUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV -RUN: rm -rf $DIR - - -CHECK: SanitizerCoverage: ./LLVMFuzzer-NullDerefTest.{{.*}}.sancov {{.*}} PCs written - -DSO: SanitizerCoverage: ./LLVMFuzzer-DSOTest.{{.*}}.sancov {{.*}} PCs written -DSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO1.{{.*}}.sancov {{.*}} PCs written -DSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO2.{{.*}}.sancov {{.*}} PCs written +RUN: rm -rf %t_workdir && mkdir -p %t_workdir +RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s +RUN: sancov -covered-functions LLVMFuzzer-NullDerefTest* %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV +RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO +RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV + +CHECK: SanitizerCoverage: {{.*}}LLVMFuzzer-NullDerefTest.{{.*}}.sancov {{.*}} PCs written +SANCOV: LLVMFuzzerTestOneInput + +DSO: SanitizerCoverage: {{.*}}LLVMFuzzer-DSOTest.{{.*}}.sancov {{.*}} PCs written +DSO-DAG: SanitizerCoverage: {{.*}}LLVMFuzzer-DSO1.{{.*}}.sancov {{.*}} PCs written +DSO-DAG: SanitizerCoverage: {{.*}}LLVMFuzzer-DSO2.{{.*}}.sancov {{.*}} PCs written NOCOV-NOT: SanitizerCoverage: {{.*}} PCs written diff --git a/lib/Fuzzer/test/equivalence-signals.test b/lib/Fuzzer/test/equivalence-signals.test new file mode 100644 index 000000000000..81a7f37602cc --- /dev/null +++ b/lib/Fuzzer/test/equivalence-signals.test @@ -0,0 +1,9 @@ +REQUIRES: posix +# Run EquivalenceATest against itself with a small timeout +# to stress the signal handling and ensure that shmem doesn't mind +# the signals. + +RUN: LLVMFuzzer-EquivalenceATest -timeout=1 -run_equivalence_server=EQUIV_SIG_TEST & export APID=$! +RUN: sleep 3 +RUN: LLVMFuzzer-EquivalenceATest -timeout=1 -use_equivalence_server=EQUIV_SIG_TEST -runs=500000 2>&1 +RUN: kill -9 $APID diff --git a/lib/Fuzzer/test/equivalence.test b/lib/Fuzzer/test/equivalence.test new file mode 100644 index 000000000000..015ba855c600 --- /dev/null +++ b/lib/Fuzzer/test/equivalence.test @@ -0,0 +1,8 @@ +REQUIRES: posix + +RUN: LLVMFuzzer-EquivalenceATest -run_equivalence_server=EQUIV_TEST & export APID=$! +RUN: sleep 3 +RUN: not LLVMFuzzer-EquivalenceBTest -use_equivalence_server=EQUIV_TEST -max_len=4096 2>&1 | FileCheck %s +CHECK: ERROR: libFuzzer: equivalence-mismatch. Sizes: {{.*}}; offset 2 +CHECK: SUMMARY: libFuzzer: equivalence-mismatch +RUN: kill -9 $APID diff --git a/lib/Fuzzer/test/extra-counters.test b/lib/Fuzzer/test/extra-counters.test new file mode 100644 index 000000000000..61fce44784b7 --- /dev/null +++ b/lib/Fuzzer/test/extra-counters.test @@ -0,0 +1,6 @@ +REQUIRES: linux + +RUN: not LLVMFuzzer-TableLookupTest -print_final_stats=1 2>&1 | FileCheck %s +CHECK: BINGO +// Expecting >= 4096 new_units_added +CHECK: stat::new_units_added:{{.*[4][0-9][0-9][0-9]}} diff --git a/lib/Fuzzer/test/fuzzer-customcrossover.test b/lib/Fuzzer/test/fuzzer-customcrossover.test index 28d39ce31dec..ccf8261af8ad 100644 --- a/lib/Fuzzer/test/fuzzer-customcrossover.test +++ b/lib/Fuzzer/test/fuzzer-customcrossover.test @@ -2,7 +2,7 @@ RUN: rm -rf %t/CustomCrossover RUN: mkdir -p %t/CustomCrossover RUN: echo "0123456789" > %t/CustomCrossover/digits RUN: echo "abcdefghij" > %t/CustomCrossover/chars -RUN: not LLVMFuzzer-CustomCrossOverTest -seed=1 -use_memcmp=0 -runs=100000 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover +RUN: not LLVMFuzzer-CustomCrossOverTest -seed=1 -runs=100000 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover RUN: rm -rf %t/CustomCrossover LLVMFuzzerCustomCrossover: In LLVMFuzzerCustomCrossover diff --git a/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test b/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test new file mode 100644 index 000000000000..1e322ec0da63 --- /dev/null +++ b/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test @@ -0,0 +1 @@ +RUN: LLVMFuzzer-CustomCrossOverAndMutateTest -seed=1 -runs=100000 diff --git a/lib/Fuzzer/test/fuzzer-dirs.test b/lib/Fuzzer/test/fuzzer-dirs.test index 63afe8dfcf9c..3de64f278f5d 100644 --- a/lib/Fuzzer/test/fuzzer-dirs.test +++ b/lib/Fuzzer/test/fuzzer-dirs.test @@ -5,9 +5,9 @@ RUN: echo b > %t/SUB1/SUB2/b RUN: echo c > %t/SUB1/SUB2/SUB3/c RUN: LLVMFuzzer-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=SUBDIRS SUBDIRS: READ units: 3 -RUN: echo zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/long +RUN: echo -n zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/long RUN: LLVMFuzzer-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=LONG -LONG: INFO: -max_len is not provided, using 94 +LONG: INFO: -max_len is not provided, using 93 RUN: rm -rf %t/SUB1 RUN: not LLVMFuzzer-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR diff --git a/lib/Fuzzer/test/fuzzer-jobs.test b/lib/Fuzzer/test/fuzzer-jobs.test deleted file mode 100644 index 5bf8cfadfb75..000000000000 --- a/lib/Fuzzer/test/fuzzer-jobs.test +++ /dev/null @@ -1,29 +0,0 @@ -RUN: rm -rf %tmp -RUN: mkdir %tmp && cd %tmp -# Create a shared corpus directory -RUN: rm -rf FuzzerJobsTestCORPUS -RUN: mkdir FuzzerJobsTestCORPUS -RUN: rm -f fuzz-{0,1}.log -# Start fuzzer and in parallel check that the output files -# that should be created exist. -RUN: LLVMFuzzer-EmptyTest -max_total_time=4 -jobs=2 -workers=2 FuzzerJobsTestCORPUS > %t-fuzzer-jobs-test.log 2>&1 & export FUZZER_PID=$! -# Wait a short while to give time for the child processes -# to start fuzzing -RUN: sleep 2 -# If the instances are running in parallel they should have created their log -# files by now. -RUN: ls fuzz-0.log -RUN: ls fuzz-1.log -# Wait for libfuzzer to finish. -# This probably isn't portable but we need a way to block until -# the fuzzer is done otherwise we might remove the files while -# they are being used. -RUN: while kill -0 ${FUZZER_PID}; do : ; done -RUN: rm -f fuzz-{0,1}.log -RUN: rm -rf FuzzerJobsTestCORPUS -RUN: FileCheck -input-file=%t-fuzzer-jobs-test.log %s -RUN: rm %t-fuzzer-jobs-test.log -RUN: cd ../ - -CHECK-DAG: Job 0 exited with exit code 0 -CHECK-DAG: Job 1 exited with exit code 0 diff --git a/lib/Fuzzer/test/fuzzer-leak.test b/lib/Fuzzer/test/fuzzer-leak.test index 9cf5c743fff5..13e3ad740e6d 100644 --- a/lib/Fuzzer/test/fuzzer-leak.test +++ b/lib/Fuzzer/test/fuzzer-leak.test @@ -29,7 +29,5 @@ RUN: not LLVMFuzzer-LeakTimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefi LEAK_TIMEOUT: ERROR: libFuzzer: timeout after LEAK_TIMEOUT-NOT: LeakSanitizer -RUN: LLVMFuzzer-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS -ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation RUN: LLVMFuzzer-LeakTest -error_exitcode=0 diff --git a/lib/Fuzzer/test/fuzzer-oom.test b/lib/Fuzzer/test/fuzzer-oom.test index 8caf649e9f04..e9d33552723e 100644 --- a/lib/Fuzzer/test/fuzzer-oom.test +++ b/lib/Fuzzer/test/fuzzer-oom.test @@ -1,10 +1,12 @@ +XFAIL: darwin RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s + CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb) CHECK: Test unit written to ./oom- SUMMARY: libFuzzer: out-of-memory -RUN: not LLVMFuzzer-OutOfMemorySingleLargeMallocTest 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC -SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory (malloc(42{{.*}})) +RUN: not LLVMFuzzer-OutOfMemorySingleLargeMallocTest -rss_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC +SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory (malloc(53{{.*}})) SINGLE_LARGE_MALLOC: in LLVMFuzzerTestOneInput # Check that -rss_limit_mb=0 means no limit. diff --git a/lib/Fuzzer/test/fuzzer-segv.test b/lib/Fuzzer/test/fuzzer-segv.test index 330f03bcc494..b9a6a5ce44ca 100644 --- a/lib/Fuzzer/test/fuzzer-segv.test +++ b/lib/Fuzzer/test/fuzzer-segv.test @@ -1,4 +1,4 @@ -RUN: ASAN_OPTIONS=handle_segv=0 not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER +RUN: env ASAN_OPTIONS=handle_segv=0 not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash- diff --git a/lib/Fuzzer/test/fuzzer-singleinputs.test b/lib/Fuzzer/test/fuzzer-singleinputs.test index ca8403bff81f..500e5da8faa9 100644 --- a/lib/Fuzzer/test/fuzzer-singleinputs.test +++ b/lib/Fuzzer/test/fuzzer-singleinputs.test @@ -8,7 +8,7 @@ RUN: echo bbb > %tmp/SINGLE_INPUTS/bbb RUN: LLVMFuzzer-SimpleTest %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS RUN: LLVMFuzzer-SimpleTest -max_len=2 %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS RUN: rm -rf %tmp/SINGLE_INPUTS -SINGLE_INPUTS: LLVMFuzzer-SimpleTest: Running 2 inputs 1 time(s) each. +SINGLE_INPUTS: LLVMFuzzer-SimpleTest{{.*}}: Running 2 inputs 1 time(s) each. SINGLE_INPUTS: aaa in SINGLE_INPUTS: bbb in SINGLE_INPUTS: NOTE: fuzzing was not performed, you have only diff --git a/lib/Fuzzer/test/fuzzer-traces-hooks.test b/lib/Fuzzer/test/fuzzer-traces-hooks.test index 71fe6f2daf11..f93a8b7199e2 100644 --- a/lib/Fuzzer/test/fuzzer-traces-hooks.test +++ b/lib/Fuzzer/test/fuzzer-traces-hooks.test @@ -1,25 +1,17 @@ -// FIXME: Support sanitizer hooks for memcmp and strcmp need -// to be implemented in the sanitizer runtime for platforms other -// than linux -REQUIRES: linux +// FIXME: Support for sanitizer hooks for memcmp and strcmp needs to +// be implemented in the sanitizer runtime for this test +UNSUPPORTED: windows CHECK: BINGO -Done1000000: Done 1000000 runs in -RUN: not LLVMFuzzer-MemcmpTest -seed=4294967295 -runs=100000 2>&1 | FileCheck %s -RUN: LLVMFuzzer-MemcmpTest -use_memcmp=0 -seed=4294967295 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000 +RUN: not LLVMFuzzer-MemcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-StrncmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-StrcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-StrstrTest -seed=1 -runs=2000000 2>&1 | FileCheck %s -RUN: not LLVMFuzzer-StrncmpTest -seed=2 -runs=100000 2>&1 | FileCheck %s -RUN: LLVMFuzzer-StrncmpTest -use_memcmp=0 -seed=3 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000 +RUN: not LLVMFuzzer-Memcmp64BytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s -RUN: not LLVMFuzzer-StrcmpTest -seed=4 -runs=200000 2>&1 | FileCheck %s -RUN: LLVMFuzzer-StrcmpTest -use_memcmp=0 -seed=5 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000 - -RUN: not LLVMFuzzer-StrstrTest -seed=6 -runs=200000 2>&1 | FileCheck %s -RUN: LLVMFuzzer-StrstrTest -use_memmem=0 -seed=7 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000 - -RUN: LLVMFuzzer-RepeatedMemcmp -seed=10 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT +RUN: LLVMFuzzer-RepeatedMemcmp -seed=11 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT RECOMMENDED_DICT:###### Recommended dictionary. ###### RECOMMENDED_DICT-DAG: "foo" RECOMMENDED_DICT-DAG: "bar" RECOMMENDED_DICT:###### End of recommended dictionary. ###### - diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test index 2f91c2195ca9..ff46d32b387d 100644 --- a/lib/Fuzzer/test/fuzzer.test +++ b/lib/Fuzzer/test/fuzzer.test @@ -11,7 +11,7 @@ MaxTotalTime: Done {{.*}} runs in {{.}} second(s) RUN: not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest RUN: not LLVMFuzzer-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest -NullDerefTest: ERROR: AddressSanitizer: SEGV on unknown address +NullDerefTest: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address NullDerefTest: Test unit written to ./crash- RUN: not LLVMFuzzer-NullDerefTest -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix NullDerefTestPrefix: Test unit written to ZZZcrash- @@ -34,7 +34,7 @@ COUNTERS: BINGO DISABLED: not LLVMFuzzer-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting. -RUN: not LLVMFuzzer-UninstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE +RUN: not LLVMFuzzer-NotinstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE NO_COVERAGE: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting RUN: not LLVMFuzzer-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB @@ -51,7 +51,10 @@ RUN: LLVMFuzzer-SimpleTest -exit_on_src_pos=SimpleTest.cpp:17 2 RUN: LLVMFuzzer-ShrinkControlFlowTest -exit_on_src_pos=ShrinkControlFlowTest.cpp:23 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS EXIT_ON_SRC_POS: INFO: found line matching '{{.*}}', exiting. -RUN: ASAN_OPTIONS=strict_string_checks=1 not LLVMFuzzer-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP +RUN: env ASAN_OPTIONS=strict_string_checks=1 not LLVMFuzzer-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP STRNCMP: AddressSanitizer: heap-buffer-overflow STRNCMP-NOT: __sanitizer_weak_hook_strncmp STRNCMP: in LLVMFuzzerTestOneInput + +RUN: not LLVMFuzzer-BogusInitializeTest 2>&1 | FileCheck %s --check-prefix=BOGUS_INITIALIZE +BOGUS_INITIALIZE: argv[0] has been modified in LLVMFuzzerInitialize diff --git a/lib/Fuzzer/test/lit.cfg b/lib/Fuzzer/test/lit.cfg index 745af0c38245..85c95b42d1ea 100644 --- a/lib/Fuzzer/test/lit.cfg +++ b/lib/Fuzzer/test/lit.cfg @@ -6,6 +6,23 @@ config.test_format = lit.formats.ShTest(True) config.suffixes = ['.test'] config.test_source_root = os.path.dirname(__file__) +# Choose between lit's internal shell pipeline runner and a real shell. If +# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. +use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") +if use_lit_shell: + # 0 is external, "" is default, and everything else is internal. + execute_external = (use_lit_shell == "0") +else: + # Otherwise we default to internal on Windows and external elsewhere, as + # bash on Windows is usually very slow. + execute_external = (not sys.platform in ['win32']) + +# testFormat: The test format to use to interpret tests. +# +# For now we require '&&' between commands, until they get globally killed and +# the test runner updated. +config.test_format = lit.formats.ShTest(execute_external) + # Tweak PATH to include llvm tools dir and current exec dir. llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) if (not llvm_tools_dir) or (not os.path.exists(llvm_tools_dir)): @@ -20,6 +37,15 @@ if config.has_lsan: else: lit_config.note('lsan feature unavailable') +if sys.platform.startswith('win') or sys.platform.startswith('cygwin'): + config.available_features.add('windows') + +if sys.platform.startswith('darwin'): + config.available_features.add('darwin') + +if config.is_posix: + config.available_features.add('posix') + if sys.platform.startswith('linux'): # Note the value of ``sys.platform`` is not consistent # between python 2 and 3, hence the use of ``.startswith()``. diff --git a/lib/Fuzzer/test/lit.site.cfg.in b/lib/Fuzzer/test/lit.site.cfg.in index 03e86c487ca9..069f2b72c0d9 100644 --- a/lib/Fuzzer/test/lit.site.cfg.in +++ b/lib/Fuzzer/test/lit.site.cfg.in @@ -1,4 +1,5 @@ config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.has_lsan = True if @HAS_LSAN@ == 1 else False +config.is_posix = @LIBFUZZER_POSIX@ lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") diff --git a/lib/Fuzzer/test/merge-posix.test b/lib/Fuzzer/test/merge-posix.test new file mode 100644 index 000000000000..47b90b986791 --- /dev/null +++ b/lib/Fuzzer/test/merge-posix.test @@ -0,0 +1,23 @@ +REQUIRES: posix + +RUN: rm -rf %tmp/T1 %tmp/T2 +RUN: mkdir -p %tmp/T1 %tmp/T2 + +RUN: echo F..... > %tmp/T1/1 +RUN: echo .U.... > %tmp/T1/2 +RUN: echo ..Z... > %tmp/T1/3 + +RUN: echo .....F > %tmp/T2/1 +RUN: echo ....U. > %tmp/T2/2 +RUN: echo ...Z.. > %tmp/T2/3 +RUN: echo ...Z.. > %tmp/T2/4 +RUN: echo ....E. > %tmp/T2/5 +RUN: echo .....R > %tmp/T2/6 + +# Check that we can report an error if file size exceeded +RUN: (ulimit -f 1; not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ) +SIGXFSZ: ERROR: libFuzzer: file size exceeded + +# Check that we honor TMPDIR +RUN: TMPDIR=DIR_DOES_NOT_EXIST not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR +TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp diff --git a/lib/Fuzzer/test/merge-summary.test b/lib/Fuzzer/test/merge-summary.test new file mode 100644 index 000000000000..df9d62dec636 --- /dev/null +++ b/lib/Fuzzer/test/merge-summary.test @@ -0,0 +1,15 @@ +RUN: rm -rf %t/T1 %t/T2 +RUN: mkdir -p %t/T0 %t/T1 %t/T2 +RUN: echo ...Z.. > %t/T2/1 +RUN: echo ....E. > %t/T2/2 +RUN: echo .....R > %t/T2/3 +RUN: echo F..... > %t/T2/a +RUN: echo .U.... > %t/T2/b +RUN: echo ..Z... > %t/T2/c + +RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY +SAVE_SUMMARY: MERGE-OUTER: writing coverage summary for 6 files to {{.*}}SUMMARY +RUN: rm %t/T1/* +RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY +LOAD_SUMMARY: MERGE-OUTER: coverage summary loaded from {{.*}}SUMMAR +LOAD_SUMMARY: MERGE-OUTER: 0 new files with 0 new features added diff --git a/lib/Fuzzer/test/merge.test b/lib/Fuzzer/test/merge.test index 5c7d30e41caa..e59da8c3e091 100644 --- a/lib/Fuzzer/test/merge.test +++ b/lib/Fuzzer/test/merge.test @@ -1,12 +1,13 @@ CHECK: BINGO -RUN: rm -rf %tmp/T1 %tmp/T2 -RUN: mkdir -p %tmp/T1 %tmp/T2 -RUN: echo F..... > %tmp/T1/1 -RUN: echo .U.... > %tmp/T1/2 -RUN: echo ..Z... > %tmp/T1/3 +RUN: rm -rf %tmp/T0 %tmp/T1 %tmp/T2 +RUN: mkdir -p %tmp/T0 %tmp/T1 %tmp/T2 +RUN: echo F..... > %tmp/T0/1 +RUN: echo .U.... > %tmp/T0/2 +RUN: echo ..Z... > %tmp/T0/3 # T1 has 3 elements, T2 is empty. +RUN: cp %tmp/T0/* %tmp/T1/ RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1 CHECK1: MERGE-OUTER: 3 files, 3 in the initial corpus CHECK1: MERGE-OUTER: 0 new files with 0 new features added @@ -29,13 +30,15 @@ CHECK3: MERGE-OUTER: 12 files, 6 in the initial corpus CHECK3: MERGE-OUTER: 0 new files with 0 new features added # Check that we respect max_len during the merge and don't crash. -RUN: rm %tmp/T1/??* +RUN: rm %tmp/T1/* +RUN: cp %tmp/T0/* %tmp/T1/ RUN: echo looooooooong > %tmp/T2/looooooooong RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN MAX_LEN: MERGE-OUTER: 3 new files # Check that merge tolerates failures. -RUN: rm %tmp/T1/??* +RUN: rm %tmp/T1/* +RUN: cp %tmp/T0/* %tmp/T1/ RUN: echo 'FUZZER' > %tmp/T2/FUZZER RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH MERGE_WITH_CRASH: MERGE-OUTER: succesfull in 2 attempt(s) @@ -45,10 +48,6 @@ MERGE_WITH_CRASH: MERGE-OUTER: 3 new files RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5 MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s) -# Check that we honor TMPDIR -RUN: TMPDIR=DIR_DOES_NOT_EXIST not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR -TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp - -# Check that we can report an error if file size exceeded -RUN: (ulimit -f 1; not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ) -SIGXFSZ: ERROR: libFuzzer: file size exceeded +RUN: rm -rf %tmp/T1/* %tmp/T2/* +RUN: not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=EMPTY +EMPTY: MERGE-OUTER: zero succesfull attempts, exiting diff --git a/lib/Fuzzer/test/minimize_crash.test b/lib/Fuzzer/test/minimize_crash.test index 7e5406598e4a..5643c6bacb09 100644 --- a/lib/Fuzzer/test/minimize_crash.test +++ b/lib/Fuzzer/test/minimize_crash.test @@ -1,6 +1,13 @@ RUN: echo 'Hi!rv349f34t3gg' > not_minimal_crash RUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s -CHECK: CRASH_MIN: failed to minimize beyond minimized-from-{{.*}} (3 bytes), exiting +CHECK: CRASH_MIN: failed to minimize beyond ./minimized-from-{{.*}} (3 bytes), exiting RUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT CHECK_EXACT: CRASH_MIN: failed to minimize beyond exact_minimized_path (3 bytes), exiting RUN: rm not_minimal_crash minimized-from-* exact_minimized_path + +RUN: echo -n 'abcd*xyz' > not_minimal_crash +RUN: LLVMFuzzer-SingleByteInputTest -minimize_crash=1 not_minimal_crash -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=MIN1 +MIN1: Test unit written to exact_minimized_path +MIN1: Test unit written to exact_minimized_path +MIN1: INFO: The input is small enough, exiting +MIN1: CRASH_MIN: failed to minimize beyond exact_minimized_path (1 bytes), exiting diff --git a/lib/Fuzzer/test/minimize_two_crashes.test b/lib/Fuzzer/test/minimize_two_crashes.test new file mode 100644 index 000000000000..2358d8c2a92e --- /dev/null +++ b/lib/Fuzzer/test/minimize_two_crashes.test @@ -0,0 +1,16 @@ +# Test that the minimizer stops when it sees a differe bug. + +RUN: rm -rf %t && mkdir %t +RUN: echo H12345678901234667888090 > %t/long_crash +RUN: env ASAN_OPTIONS=dedup_token_length=3 LLVMFuzzer-TwoDifferentBugsTest -seed=1 -minimize_crash=1 %t/long_crash -exact_artifact_path=%t/result 2>&1 | FileCheck %s + +CHECK: DedupToken1: DEDUP_TOKEN: Bar +CHECK: DedupToken2: DEDUP_TOKEN: Bar +CHECK: DedupToken1: DEDUP_TOKEN: Bar +CHECK: DedupToken2: DEDUP_TOKEN: Foo +CHECK: CRASH_MIN: mismatch in dedup tokens + +RUN: not LLVMFuzzer-TwoDifferentBugsTest %t/result 2>&1 | FileCheck %s --check-prefix=VERIFY + +VERIFY: ERROR: AddressSanitizer: +VERIFY: in Bar diff --git a/lib/Fuzzer/test/no-coverage/CMakeLists.txt b/lib/Fuzzer/test/no-coverage/CMakeLists.txt index d2f6f438ad79..52e7240333ee 100644 --- a/lib/Fuzzer/test/no-coverage/CMakeLists.txt +++ b/lib/Fuzzer/test/no-coverage/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard") set(NoCoverageTests - UninstrumentedTest + NotinstrumentedTest ) foreach(Test ${NoCoverageTests}) @@ -16,14 +16,14 @@ endforeach() ############################################################################### # AFL Driver test ############################################################################### +if(NOT MSVC) + add_executable(AFLDriverTest + ../AFLDriverTest.cpp ../../afl/afl_driver.cpp) -add_executable(AFLDriverTest - ../AFLDriverTest.cpp ../../afl/afl_driver.cpp) + set_target_properties(AFLDriverTest + PROPERTIES RUNTIME_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" + ) -set_target_properties(AFLDriverTest - PROPERTIES RUNTIME_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/lib/Fuzzer/test" - ) - -# Propagate value into parent directory -set(TestBinaries ${TestBinaries} AFLDriverTest PARENT_SCOPE) + add_dependencies(TestBinaries AFLDriverTest) +endif() diff --git a/lib/Fuzzer/test/trace-malloc-2.test b/lib/Fuzzer/test/trace-malloc-2.test new file mode 100644 index 000000000000..7719b650c791 --- /dev/null +++ b/lib/Fuzzer/test/trace-malloc-2.test @@ -0,0 +1,8 @@ +// FIXME: This test infinite loops on darwin because it crashes +// printing a stack trace repeatedly +UNSUPPORTED: darwin + +RUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2 +TRACE2-DAG: FREE[0] +TRACE2-DAG: MALLOC[0] +TRACE2-DAG: in LLVMFuzzerTestOneInput diff --git a/lib/Fuzzer/test/trace-malloc.test b/lib/Fuzzer/test/trace-malloc.test index c95147904d42..25694cc2de5c 100644 --- a/lib/Fuzzer/test/trace-malloc.test +++ b/lib/Fuzzer/test/trace-malloc.test @@ -3,8 +3,3 @@ CHECK-DAG: MallocFreeTracer: STOP 0 0 (same) CHECK-DAG: MallocFreeTracer: STOP 0 1 (DIFFERENT) CHECK-DAG: MallocFreeTracer: STOP 1 0 (DIFFERENT) CHECK-DAG: MallocFreeTracer: STOP 1 1 (same) - -RUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2 -TRACE2-DAG: FREE[0] -TRACE2-DAG: MALLOC[0] -TRACE2-DAG: in LLVMFuzzerTestOneInput diff --git a/lib/Fuzzer/test/trace-pc.test b/lib/Fuzzer/test/trace-pc.test new file mode 100644 index 000000000000..3709677b71b6 --- /dev/null +++ b/lib/Fuzzer/test/trace-pc.test @@ -0,0 +1,2 @@ +CHECK: BINGO +RUN: LLVMFuzzer-SimpleTest-TracePC -runs=100000 -seed=1 2>&1 | FileCheck %s diff --git a/lib/Fuzzer/test/trace-pc/CMakeLists.txt b/lib/Fuzzer/test/trace-pc/CMakeLists.txt new file mode 100644 index 000000000000..e800f82cc5dc --- /dev/null +++ b/lib/Fuzzer/test/trace-pc/CMakeLists.txt @@ -0,0 +1,13 @@ +# These tests are not instrumented with coverage and don't +# have coverage rt in the binary. + +set(CMAKE_CXX_FLAGS + "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -fsanitize-coverage=trace-pc") + +set(TracePCTests + SimpleTest + ) + +foreach(Test ${TracePCTests}) + add_libfuzzer_test(${Test}-TracePC SOURCES ../${Test}.cpp) +endforeach() diff --git a/lib/Fuzzer/test/ubsan/CMakeLists.txt b/lib/Fuzzer/test/ubsan/CMakeLists.txt index 7a9eacdbe7df..55e0a118186b 100644 --- a/lib/Fuzzer/test/ubsan/CMakeLists.txt +++ b/lib/Fuzzer/test/ubsan/CMakeLists.txt @@ -10,6 +10,3 @@ set(UbsanTests foreach(Test ${UbsanTests}) add_libfuzzer_test(${Test}-Ubsan SOURCES ../${Test}.cpp) endforeach() - -# Propagate value into parent directory -set(TestBinaries ${TestBinaries} PARENT_SCOPE) diff --git a/lib/Fuzzer/test/ulimit.test b/lib/Fuzzer/test/ulimit.test index a60636c351bd..c2faca13f728 100644 --- a/lib/Fuzzer/test/ulimit.test +++ b/lib/Fuzzer/test/ulimit.test @@ -1,2 +1,4 @@ +REQUIRES: posix + RUN: ulimit -s 1000 RUN: LLVMFuzzer-SimpleTest diff --git a/lib/Fuzzer/test/uninstrumented/CMakeLists.txt b/lib/Fuzzer/test/uninstrumented/CMakeLists.txt index 29b66e6e586a..f4ab59e5b18d 100644 --- a/lib/Fuzzer/test/uninstrumented/CMakeLists.txt +++ b/lib/Fuzzer/test/uninstrumented/CMakeLists.txt @@ -11,6 +11,3 @@ set(UninstrumentedTests foreach(Test ${UninstrumentedTests}) add_libfuzzer_test(${Test}-Uninstrumented SOURCES ../${Test}.cpp) endforeach() - -# Propagate value into parent directory -set(TestBinaries ${TestBinaries} PARENT_SCOPE) diff --git a/lib/Fuzzer/test/value-profile-div.test b/lib/Fuzzer/test/value-profile-div.test index ba45e4129d30..b966a8916512 100644 --- a/lib/Fuzzer/test/value-profile-div.test +++ b/lib/Fuzzer/test/value-profile-div.test @@ -1,3 +1,3 @@ -CHECK: AddressSanitizer: FPE +CHECK: AddressSanitizer: {{FPE|int-divide-by-zero}} RUN: not LLVMFuzzer-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/lib/Fuzzer/test/value-profile-mem.test b/lib/Fuzzer/test/value-profile-mem.test index 09d737dbe736..880b2692910a 100644 --- a/lib/Fuzzer/test/value-profile-mem.test +++ b/lib/Fuzzer/test/value-profile-mem.test @@ -1,2 +1,2 @@ CHECK: BINGO -RUN: not LLVMFuzzer-SingleMemcmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-SingleMemcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/lib/Fuzzer/test/value-profile-strcmp.test b/lib/Fuzzer/test/value-profile-strcmp.test index 1e7ef9b45e96..7f1047594548 100644 --- a/lib/Fuzzer/test/value-profile-strcmp.test +++ b/lib/Fuzzer/test/value-profile-strcmp.test @@ -1,2 +1,2 @@ CHECK: BINGO -RUN: not LLVMFuzzer-SingleStrcmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-SingleStrcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s diff --git a/lib/Fuzzer/test/value-profile-strncmp.test b/lib/Fuzzer/test/value-profile-strncmp.test index 650973180c06..84a74c4f0ad2 100644 --- a/lib/Fuzzer/test/value-profile-strncmp.test +++ b/lib/Fuzzer/test/value-profile-strncmp.test @@ -1,2 +1,2 @@ CHECK: BINGO -RUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s |