From f8fa2fcad0a09166b53827fae7553ae6012b30b2 Mon Sep 17 00:00:00 2001 From: bambam Date: Sat, 9 May 2020 14:53:05 +0000 Subject: [PATCH 1/2] Added support for afl-clang-fast. --- zcutil/afl/afl-run.sh | 2 +- zcutil/afl/zcash-wrapper | 21 ++++++++++++++++----- zcutil/afl/zcash-wrapper-clang | 1 + zcutil/afl/zcash-wrapper-clang++ | 1 + 4 files changed, 19 insertions(+), 6 deletions(-) create mode 120000 zcutil/afl/zcash-wrapper-clang create mode 120000 zcutil/afl/zcash-wrapper-clang++ diff --git a/zcutil/afl/afl-run.sh b/zcutil/afl/afl-run.sh index 6cbfffee3..f29368265 100755 --- a/zcutil/afl/afl-run.sh +++ b/zcutil/afl/afl-run.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -eu -o pipefail +set -exu -o pipefail for d in src/fuzzing/*/ ; do fuzz_cases+="$(basename "$d"), " diff --git a/zcutil/afl/zcash-wrapper b/zcutil/afl/zcash-wrapper index 2b5b2434d..950c3ea03 100755 --- a/zcutil/afl/zcash-wrapper +++ b/zcutil/afl/zcash-wrapper @@ -2,7 +2,6 @@ set -ex -o pipefail -export ARGS=$@ instrument=( "\/src$" @@ -22,10 +21,22 @@ fi case $0 in *zcash-wrapper-g++) - COMPILER="g++" + OCOMPILER="g++" + ACOMPILER=$OCOMPILER ;; *zcash-wrapper-gcc) - COMPILER="gcc" + OCOMPILER="gcc" + ACOMPILER=$OCOMPILER + ;; +*zcash-wrapper-clang) + OCOMPILER="clang-6.0" + ACOMPILER="clang-fast" + CFLAGS="-fsanitize=address -static" + ;; +*zcash-wrapper-clang++) + OCOMPILER="clang++-6.0" + ACOMPILER="clang-fast++" + CPPFLAGS="-fsanitize=address -static" ;; *zcash-wrapper) echo "Call this script instead of your regular compiler, and if the absolute path of the CWD the wrapper was called from matches a regex in the array 'instrument', it will call AFL to instrument the resulting binary. Otherwise it will call either g++ or gcc depending on how it was invoked. \$AFL_INSTALL_DIR must be set to the path where AFL is installed." @@ -40,9 +51,9 @@ do if echo -- "`pwd`" | grep "$i"; then # We found a match, let's instrument this one. echo "Matched directory `pwd` to instrument element $i. Instrumenting this call." >> "$AFL_LOG_DIR/zcash-build-wrapper.log" - exec -- "$AFL_INSTALL_DIR/afl-$COMPILER" "$@" + exec -- "$AFL_INSTALL_DIR/afl-$ACOMPILER" "$@" fi done # No match, just pass-through. -exec -- "$COMPILER" "$@" +exec -- "$OCOMPILER" "$@" diff --git a/zcutil/afl/zcash-wrapper-clang b/zcutil/afl/zcash-wrapper-clang new file mode 120000 index 000000000..e640aa6e1 --- /dev/null +++ b/zcutil/afl/zcash-wrapper-clang @@ -0,0 +1 @@ +zcash-wrapper \ No newline at end of file diff --git a/zcutil/afl/zcash-wrapper-clang++ b/zcutil/afl/zcash-wrapper-clang++ new file mode 120000 index 000000000..e640aa6e1 --- /dev/null +++ b/zcutil/afl/zcash-wrapper-clang++ @@ -0,0 +1 @@ +zcash-wrapper \ No newline at end of file From 58dda603a4c569946a5ee607ace4d15b1f87d660 Mon Sep 17 00:00:00 2001 From: bambam Date: Sat, 9 May 2020 21:30:32 +0000 Subject: [PATCH 2/2] Added libfuzzer support. --- src/fuzzing/CheckBlock/fuzz.cpp | 67 ++++++-- src/fuzzing/DecodeHexTx/fuzz.cpp | 22 +++ src/fuzzing/DeserializeAddrMan/fuzz.cpp | 20 +++ src/fuzzing/DeserializeTx/fuzz.cpp | 22 +++ src/fuzzing/ReadFeeEstimates/fuzz.cpp | 21 +++ src/fuzzing/UniValue__Read/dict | 7 + src/fuzzing/UniValue__Read/fuzz.cpp | 29 ++++ src/fuzzing/UniValue__Read/input/fail1.json | 1 + src/fuzzing/UniValue__Read/input/fail10.json | 1 + src/fuzzing/UniValue__Read/input/fail11.json | 1 + src/fuzzing/UniValue__Read/input/fail12.json | 1 + src/fuzzing/UniValue__Read/input/fail13.json | 1 + src/fuzzing/UniValue__Read/input/fail14.json | 1 + src/fuzzing/UniValue__Read/input/fail15.json | 1 + src/fuzzing/UniValue__Read/input/fail16.json | 1 + src/fuzzing/UniValue__Read/input/fail17.json | 1 + src/fuzzing/UniValue__Read/input/fail18.json | 1 + src/fuzzing/UniValue__Read/input/fail19.json | 1 + src/fuzzing/UniValue__Read/input/fail2.json | 1 + src/fuzzing/UniValue__Read/input/fail20.json | 1 + src/fuzzing/UniValue__Read/input/fail21.json | 1 + src/fuzzing/UniValue__Read/input/fail22.json | 1 + src/fuzzing/UniValue__Read/input/fail23.json | 1 + src/fuzzing/UniValue__Read/input/fail24.json | 1 + src/fuzzing/UniValue__Read/input/fail25.json | 1 + src/fuzzing/UniValue__Read/input/fail26.json | 1 + src/fuzzing/UniValue__Read/input/fail27.json | 2 + src/fuzzing/UniValue__Read/input/fail28.json | 2 + src/fuzzing/UniValue__Read/input/fail29.json | 1 + src/fuzzing/UniValue__Read/input/fail3.json | 1 + src/fuzzing/UniValue__Read/input/fail30.json | 1 + src/fuzzing/UniValue__Read/input/fail31.json | 1 + src/fuzzing/UniValue__Read/input/fail32.json | 1 + src/fuzzing/UniValue__Read/input/fail33.json | 1 + src/fuzzing/UniValue__Read/input/fail34.json | 1 + src/fuzzing/UniValue__Read/input/fail35.json | 1 + src/fuzzing/UniValue__Read/input/fail36.json | 1 + src/fuzzing/UniValue__Read/input/fail37.json | 1 + src/fuzzing/UniValue__Read/input/fail38.json | 1 + src/fuzzing/UniValue__Read/input/fail39.json | 1 + src/fuzzing/UniValue__Read/input/fail4.json | 1 + src/fuzzing/UniValue__Read/input/fail40.json | 1 + src/fuzzing/UniValue__Read/input/fail41.json | 1 + src/fuzzing/UniValue__Read/input/fail42.json | Bin 0 -> 37 bytes src/fuzzing/UniValue__Read/input/fail5.json | 1 + src/fuzzing/UniValue__Read/input/fail6.json | 1 + src/fuzzing/UniValue__Read/input/fail7.json | 1 + src/fuzzing/UniValue__Read/input/fail8.json | 1 + src/fuzzing/UniValue__Read/input/fail9.json | 1 + src/fuzzing/UniValue__Read/input/pass1.json | 58 +++++++ src/fuzzing/UniValue__Read/input/pass2.json | 1 + src/fuzzing/UniValue__Read/input/pass3.json | 6 + src/fuzzing/UniValue__Read/input/round1.json | 1 + src/fuzzing/UniValue__Read/input/round2.json | 1 + src/fuzzing/UniValue__Read/input/round3.json | 1 + src/fuzzing/UniValue__Read/input/round4.json | 1 + src/fuzzing/UniValue__Read/input/round5.json | 1 + src/fuzzing/UniValue__Read/input/round6.json | 1 + src/fuzzing/UniValue__Read/input/round7.json | 1 + zcutil/build.sh | 7 + zcutil/libfuzzer/libfuzzer-build.sh | 151 +++++++++++++++++++ zcutil/libfuzzer/zcash-wrapper | 123 +++++++++++++++ zcutil/libfuzzer/zcash-wrapper-clang | 1 + zcutil/libfuzzer/zcash-wrapper-clang++ | 1 + 64 files changed, 571 insertions(+), 15 deletions(-) create mode 100644 src/fuzzing/UniValue__Read/dict create mode 100644 src/fuzzing/UniValue__Read/fuzz.cpp create mode 100644 src/fuzzing/UniValue__Read/input/fail1.json create mode 100644 src/fuzzing/UniValue__Read/input/fail10.json create mode 100644 src/fuzzing/UniValue__Read/input/fail11.json create mode 100644 src/fuzzing/UniValue__Read/input/fail12.json create mode 100644 src/fuzzing/UniValue__Read/input/fail13.json create mode 100644 src/fuzzing/UniValue__Read/input/fail14.json create mode 100644 src/fuzzing/UniValue__Read/input/fail15.json create mode 100644 src/fuzzing/UniValue__Read/input/fail16.json create mode 100644 src/fuzzing/UniValue__Read/input/fail17.json create mode 100644 src/fuzzing/UniValue__Read/input/fail18.json create mode 100644 src/fuzzing/UniValue__Read/input/fail19.json create mode 100644 src/fuzzing/UniValue__Read/input/fail2.json create mode 100644 src/fuzzing/UniValue__Read/input/fail20.json create mode 100644 src/fuzzing/UniValue__Read/input/fail21.json create mode 100644 src/fuzzing/UniValue__Read/input/fail22.json create mode 100644 src/fuzzing/UniValue__Read/input/fail23.json create mode 100644 src/fuzzing/UniValue__Read/input/fail24.json create mode 100644 src/fuzzing/UniValue__Read/input/fail25.json create mode 100644 src/fuzzing/UniValue__Read/input/fail26.json create mode 100644 src/fuzzing/UniValue__Read/input/fail27.json create mode 100644 src/fuzzing/UniValue__Read/input/fail28.json create mode 100644 src/fuzzing/UniValue__Read/input/fail29.json create mode 100644 src/fuzzing/UniValue__Read/input/fail3.json create mode 100644 src/fuzzing/UniValue__Read/input/fail30.json create mode 100644 src/fuzzing/UniValue__Read/input/fail31.json create mode 100644 src/fuzzing/UniValue__Read/input/fail32.json create mode 100644 src/fuzzing/UniValue__Read/input/fail33.json create mode 100644 src/fuzzing/UniValue__Read/input/fail34.json create mode 100644 src/fuzzing/UniValue__Read/input/fail35.json create mode 100644 src/fuzzing/UniValue__Read/input/fail36.json create mode 100644 src/fuzzing/UniValue__Read/input/fail37.json create mode 100644 src/fuzzing/UniValue__Read/input/fail38.json create mode 100644 src/fuzzing/UniValue__Read/input/fail39.json create mode 100644 src/fuzzing/UniValue__Read/input/fail4.json create mode 100644 src/fuzzing/UniValue__Read/input/fail40.json create mode 100644 src/fuzzing/UniValue__Read/input/fail41.json create mode 100644 src/fuzzing/UniValue__Read/input/fail42.json create mode 100644 src/fuzzing/UniValue__Read/input/fail5.json create mode 100644 src/fuzzing/UniValue__Read/input/fail6.json create mode 100644 src/fuzzing/UniValue__Read/input/fail7.json create mode 100644 src/fuzzing/UniValue__Read/input/fail8.json create mode 100644 src/fuzzing/UniValue__Read/input/fail9.json create mode 100644 src/fuzzing/UniValue__Read/input/pass1.json create mode 100644 src/fuzzing/UniValue__Read/input/pass2.json create mode 100644 src/fuzzing/UniValue__Read/input/pass3.json create mode 100644 src/fuzzing/UniValue__Read/input/round1.json create mode 100644 src/fuzzing/UniValue__Read/input/round2.json create mode 100644 src/fuzzing/UniValue__Read/input/round3.json create mode 100644 src/fuzzing/UniValue__Read/input/round4.json create mode 100644 src/fuzzing/UniValue__Read/input/round5.json create mode 100644 src/fuzzing/UniValue__Read/input/round6.json create mode 100644 src/fuzzing/UniValue__Read/input/round7.json create mode 100755 zcutil/libfuzzer/libfuzzer-build.sh create mode 100755 zcutil/libfuzzer/zcash-wrapper create mode 120000 zcutil/libfuzzer/zcash-wrapper-clang create mode 120000 zcutil/libfuzzer/zcash-wrapper-clang++ diff --git a/src/fuzzing/CheckBlock/fuzz.cpp b/src/fuzzing/CheckBlock/fuzz.cpp index 57ab7b4eb..4757ab4ca 100644 --- a/src/fuzzing/CheckBlock/fuzz.cpp +++ b/src/fuzzing/CheckBlock/fuzz.cpp @@ -2,11 +2,43 @@ #include "chainparams.h" #include "proof_verifier.h" -int main (int argc, char *argv[]) { +extern bool CheckBlock( + const CBlock& block, + CValidationState& state, + const CChainParams& chainparams, + libzcash::ProofVerifier& verifier, + bool fCheckPOW = true, + bool fCheckMerkleRoot = true); + +bool init_done = false; + +const CChainParams& chainparams = NULL; +auto verifier = libzcash::ProofVerifier::Strict(); + + +int fuzz_CheckBlock(CBlock block) { int retval = 0; - SelectParams(CBaseChainParams::MAIN); + if (!init_done) { + SelectParams(CBaseChainParams::MAIN); + chainparams = Params() + init_done = true; + } + CValidationState state; + + // We don't check the PoW or Merkle tree root in order to reach more code. + + if (!CheckBlock(block, state, chainparams, verifier, false, false)) { + retval = -1; + } + + return retval; +} + +#ifdef FUZZ_WITH_AFL + +int main (int argc, char *argv[]) { CBlock block; CAutoFile filein(fopen(argv[1], "rb"), SER_DISK, CLIENT_VERSION); try { @@ -14,17 +46,22 @@ int main (int argc, char *argv[]) { } catch (const std::exception& e) { return -1; } - - // We don't load the SNARK parameters because it's too slow. This means that - // valid blocks with shielded transactions will generate a crash. - - const CChainParams& chainparams = Params(); - auto verifier = ProofVerifier::Disabled(); - CValidationState state; - // We don't check the PoW or Merkle tree root in order to reach more code. - if (!CheckBlock(block, state, chainparams, verifier, false, false)) { - retval = -1; - } - - return retval; + return fuzz_CheckBlock(block); } + +#endif // FUZZ_WITH_AFL +#ifdef FUZZ_WITH_LIBFUZZER + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + CBlock block; + CDataStream ds((const char *)Data, (const char *)Data+Size, SER_NETWORK, PROTOCOL_VERSION); + try { + ds >> block; + } catch (const std::exception &e) { + return -1; + } + fuzz_CheckBlock(block); + return 0; // Non-zero return values are reserved for future use. +} + +#endif diff --git a/src/fuzzing/DecodeHexTx/fuzz.cpp b/src/fuzzing/DecodeHexTx/fuzz.cpp index 6e8f0e9f4..8cf74d503 100644 --- a/src/fuzzing/DecodeHexTx/fuzz.cpp +++ b/src/fuzzing/DecodeHexTx/fuzz.cpp @@ -1,10 +1,18 @@ +#include +#include + extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); +// actual fuzzer + bool fuzz_DecodeHexTxFunction (const std::string& strHexTx) { CTransaction tx; return DecodeHexTx(tx, strHexTx); } +#ifdef FUZZ_WITH_AFL + +// AFL int fuzz_DecodeHexTx (int argc, char *argv[]) { std::ifstream t(argv[1]); @@ -15,3 +23,17 @@ int fuzz_DecodeHexTx (int argc, char *argv[]) { } int main (int argc, char *argv[]) { return fuzz_DecodeHexTx(argc, argv); } + +#endif +#ifdef FUZZ_WITH_LIBFUZZER + +// libfuzzer + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + std::string s; + s.assign((const char *)Data, Size); + fuzz_DecodeHexTxFunction (s); + return 0; // Non-zero return values are reserved for future use. +} + +#endif diff --git a/src/fuzzing/DeserializeAddrMan/fuzz.cpp b/src/fuzzing/DeserializeAddrMan/fuzz.cpp index 1b520efc8..2ffdec11d 100644 --- a/src/fuzzing/DeserializeAddrMan/fuzz.cpp +++ b/src/fuzzing/DeserializeAddrMan/fuzz.cpp @@ -1,6 +1,9 @@ #include "addrman.h" #include "streams.h" + +#ifdef FUZZ_WITH_AFL + int main (int argc, char *argv[]) { CAddrMan addrman; CAutoFile filein(fopen(argv[1], "rb"), SER_DISK, CLIENT_VERSION); @@ -11,3 +14,20 @@ int main (int argc, char *argv[]) { return -1; } } + +#endif + +#ifdef FUZZ_WITH_LIBFUZZER + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + CAddrMan addrman; + CDataStream ds(Data, Data+Size, SER_DISK, CLIENT_VERSION); + try { + ds >> addrman; + } catch (const std::exception &e) { + return 0; + } + return 0; // Non-zero return values are reserved for future use. +} + +#endif diff --git a/src/fuzzing/DeserializeTx/fuzz.cpp b/src/fuzzing/DeserializeTx/fuzz.cpp index 0eedf4be4..39b66228b 100644 --- a/src/fuzzing/DeserializeTx/fuzz.cpp +++ b/src/fuzzing/DeserializeTx/fuzz.cpp @@ -1,3 +1,7 @@ +#include + +// actual fuzzer + bool fuzz_TxDeserializeFunction (const std::vector txData) { CTransaction tx; CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); @@ -9,6 +13,9 @@ bool fuzz_TxDeserializeFunction (const std::vector txData) { } } +#ifdef FUZZ_WITH_AFL + +// AFL int fuzz_TxDeserialize (int argc, char *argv[]) { std::ifstream t(argv[1]); @@ -19,3 +26,18 @@ int fuzz_TxDeserialize (int argc, char *argv[]) { } int main (int argc, char *argv[]) { return fuzz_TxDeserialize(argc, argv); } + +#endif + +#ifdef FUZZ_WITH_LIBFUZZER + +// libFuzzer + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + std::vector vect(Size); + memcpy(vect.data(), Data, Size); + fuzz_TxDeserializeFunction(vect); + return 0; // Non-zero return values are reserved for future use. +} + +#endif diff --git a/src/fuzzing/ReadFeeEstimates/fuzz.cpp b/src/fuzzing/ReadFeeEstimates/fuzz.cpp index 1bdf2cf1d..e066fc792 100644 --- a/src/fuzzing/ReadFeeEstimates/fuzz.cpp +++ b/src/fuzzing/ReadFeeEstimates/fuzz.cpp @@ -1,5 +1,7 @@ #include "txmempool.h" +#ifdef FUZZ_WITH_AFL + int main (int argc, char *argv[]) { CFeeRate rate; CTxMemPool mempool(rate); @@ -11,3 +13,22 @@ int main (int argc, char *argv[]) { return -1; } } + +#endif + +#ifdef FUZZ_WITH_LIBFUZZER + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + CFeeRate rate; + CTxMemPool mempool(rate); + CAutoFile est_filein(fmemopen(Data, Size, "rb"), SER_DISK, CLIENT_VERSION); + + if (mempool.ReadFeeEstimates(est_filein)) { + return 0; + } else { + return -1; + } +} + + +#endif diff --git a/src/fuzzing/UniValue__Read/dict b/src/fuzzing/UniValue__Read/dict new file mode 100644 index 000000000..bbf7ec5df --- /dev/null +++ b/src/fuzzing/UniValue__Read/dict @@ -0,0 +1,7 @@ +kw1="{" +kw2="}" +kw5="[" +kw6="]" +kw7=":" +kw8="," +kw9="\"" diff --git a/src/fuzzing/UniValue__Read/fuzz.cpp b/src/fuzzing/UniValue__Read/fuzz.cpp new file mode 100644 index 000000000..90409b147 --- /dev/null +++ b/src/fuzzing/UniValue__Read/fuzz.cpp @@ -0,0 +1,29 @@ +#include "univalue.h" + +int fuzz_UniValue_Read(std::string notquitejson) { + UniValue valRequest; + if (!valRequest.read(notquitejson)) { + return -1; + } + return 0; +} + +#ifdef FUZZ_WITH_AFL + +#error "The AFL version of this fuzzer has not yet been implemented." + +int main (int argc, char *argv[]) { + // not implemented + return 0; +} + +#endif // FUZZ_WITH_AFL +#ifdef FUZZ_WITH_LIBFUZZER + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + std::string s; + s.assign((const char *)Data, Size); + return fuzz_UniValue_Read(s); +} + +#endif diff --git a/src/fuzzing/UniValue__Read/input/fail1.json b/src/fuzzing/UniValue__Read/input/fail1.json new file mode 100644 index 000000000..8feb01a6d --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail1.json @@ -0,0 +1 @@ +"This is a string that never ends, yes it goes on and on, my friends. diff --git a/src/fuzzing/UniValue__Read/input/fail10.json b/src/fuzzing/UniValue__Read/input/fail10.json new file mode 100644 index 000000000..5d8c0047b --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail11.json b/src/fuzzing/UniValue__Read/input/fail11.json new file mode 100644 index 000000000..76eb95b45 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail12.json b/src/fuzzing/UniValue__Read/input/fail12.json new file mode 100644 index 000000000..77580a452 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail13.json b/src/fuzzing/UniValue__Read/input/fail13.json new file mode 100644 index 000000000..379406b59 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail14.json b/src/fuzzing/UniValue__Read/input/fail14.json new file mode 100644 index 000000000..0ed366b38 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail15.json b/src/fuzzing/UniValue__Read/input/fail15.json new file mode 100644 index 000000000..fc8376b60 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail16.json b/src/fuzzing/UniValue__Read/input/fail16.json new file mode 100644 index 000000000..3fe21d4b5 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail16.json @@ -0,0 +1 @@ +[\naked] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail17.json b/src/fuzzing/UniValue__Read/input/fail17.json new file mode 100644 index 000000000..62b9214ae --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail18.json b/src/fuzzing/UniValue__Read/input/fail18.json new file mode 100644 index 000000000..edac92716 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail18.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail19.json b/src/fuzzing/UniValue__Read/input/fail19.json new file mode 100644 index 000000000..3b9c46fa9 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail2.json b/src/fuzzing/UniValue__Read/input/fail2.json new file mode 100644 index 000000000..6b7c11e5a --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail2.json @@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail20.json b/src/fuzzing/UniValue__Read/input/fail20.json new file mode 100644 index 000000000..27c1af3e7 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail21.json b/src/fuzzing/UniValue__Read/input/fail21.json new file mode 100644 index 000000000..62474573b --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail22.json b/src/fuzzing/UniValue__Read/input/fail22.json new file mode 100644 index 000000000..a7752581b --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail23.json b/src/fuzzing/UniValue__Read/input/fail23.json new file mode 100644 index 000000000..494add1ca --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail23.json @@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail24.json b/src/fuzzing/UniValue__Read/input/fail24.json new file mode 100644 index 000000000..caff239bf --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail24.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail25.json b/src/fuzzing/UniValue__Read/input/fail25.json new file mode 100644 index 000000000..8b7ad23e0 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail25.json @@ -0,0 +1 @@ +[" tab character in string "] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail26.json b/src/fuzzing/UniValue__Read/input/fail26.json new file mode 100644 index 000000000..845d26a6a --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail27.json b/src/fuzzing/UniValue__Read/input/fail27.json new file mode 100644 index 000000000..6b01a2ca4 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail27.json @@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail28.json b/src/fuzzing/UniValue__Read/input/fail28.json new file mode 100644 index 000000000..621a0101c --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail29.json b/src/fuzzing/UniValue__Read/input/fail29.json new file mode 100644 index 000000000..47ec421bb --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail29.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail3.json b/src/fuzzing/UniValue__Read/input/fail3.json new file mode 100644 index 000000000..168c81eb7 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail3.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail30.json b/src/fuzzing/UniValue__Read/input/fail30.json new file mode 100644 index 000000000..8ab0bc4b8 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail30.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail31.json b/src/fuzzing/UniValue__Read/input/fail31.json new file mode 100644 index 000000000..1cce602b5 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail31.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail32.json b/src/fuzzing/UniValue__Read/input/fail32.json new file mode 100644 index 000000000..45cba7396 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail33.json b/src/fuzzing/UniValue__Read/input/fail33.json new file mode 100644 index 000000000..ca5eb19dc --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail33.json @@ -0,0 +1 @@ +["mismatch"} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail34.json b/src/fuzzing/UniValue__Read/input/fail34.json new file mode 100644 index 000000000..3f8be1728 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail34.json @@ -0,0 +1 @@ +{} garbage \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail35.json b/src/fuzzing/UniValue__Read/input/fail35.json new file mode 100644 index 000000000..de30ca5c4 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail35.json @@ -0,0 +1 @@ +[ true true true [] [] [] ] diff --git a/src/fuzzing/UniValue__Read/input/fail36.json b/src/fuzzing/UniValue__Read/input/fail36.json new file mode 100644 index 000000000..f82eb8e1f --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail36.json @@ -0,0 +1 @@ +{"a":} diff --git a/src/fuzzing/UniValue__Read/input/fail37.json b/src/fuzzing/UniValue__Read/input/fail37.json new file mode 100644 index 000000000..3294dc3a4 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail37.json @@ -0,0 +1 @@ +{"a":1 "b":2} diff --git a/src/fuzzing/UniValue__Read/input/fail38.json b/src/fuzzing/UniValue__Read/input/fail38.json new file mode 100644 index 000000000..b245e2e46 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail38.json @@ -0,0 +1 @@ +["\ud834"] diff --git a/src/fuzzing/UniValue__Read/input/fail39.json b/src/fuzzing/UniValue__Read/input/fail39.json new file mode 100644 index 000000000..7c9e263f2 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail39.json @@ -0,0 +1 @@ +["\udd61"] diff --git a/src/fuzzing/UniValue__Read/input/fail4.json b/src/fuzzing/UniValue__Read/input/fail4.json new file mode 100644 index 000000000..9de168bf3 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail4.json @@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail40.json b/src/fuzzing/UniValue__Read/input/fail40.json new file mode 100644 index 000000000..664dc9e24 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail40.json @@ -0,0 +1 @@ +["…ก"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail41.json b/src/fuzzing/UniValue__Read/input/fail41.json new file mode 100644 index 000000000..0de342a2b --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail41.json @@ -0,0 +1 @@ +["๐…"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail42.json b/src/fuzzing/UniValue__Read/input/fail42.json new file mode 100644 index 0000000000000000000000000000000000000000..9c7565adbddf645df5edfbdcd630c7a0f94aa2eb GIT binary patch literal 37 kcma!6N=i-3FG^L&E6q_zsw_!Wie*qrOe;w(LWpny0Pvs;RsaA1 literal 0 HcmV?d00001 diff --git a/src/fuzzing/UniValue__Read/input/fail5.json b/src/fuzzing/UniValue__Read/input/fail5.json new file mode 100644 index 000000000..ddf3ce3d2 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail5.json @@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail6.json b/src/fuzzing/UniValue__Read/input/fail6.json new file mode 100644 index 000000000..ed91580e1 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail6.json @@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail7.json b/src/fuzzing/UniValue__Read/input/fail7.json new file mode 100644 index 000000000..8a96af3e4 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail7.json @@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail8.json b/src/fuzzing/UniValue__Read/input/fail8.json new file mode 100644 index 000000000..b28479c6e --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail8.json @@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/fail9.json b/src/fuzzing/UniValue__Read/input/fail9.json new file mode 100644 index 000000000..5815574f3 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/fail9.json @@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/pass1.json b/src/fuzzing/UniValue__Read/input/pass1.json new file mode 100644 index 000000000..70e268543 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/pass2.json b/src/fuzzing/UniValue__Read/input/pass2.json new file mode 100644 index 000000000..d3c63c7ad --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/src/fuzzing/UniValue__Read/input/pass3.json b/src/fuzzing/UniValue__Read/input/pass3.json new file mode 100644 index 000000000..4528d51f1 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/src/fuzzing/UniValue__Read/input/round1.json b/src/fuzzing/UniValue__Read/input/round1.json new file mode 100644 index 000000000..a711e7308 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round1.json @@ -0,0 +1 @@ +["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f"] diff --git a/src/fuzzing/UniValue__Read/input/round2.json b/src/fuzzing/UniValue__Read/input/round2.json new file mode 100644 index 000000000..b766cccc6 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round2.json @@ -0,0 +1 @@ +["aยงโ– ๐Ž’๐…ก"] diff --git a/src/fuzzing/UniValue__Read/input/round3.json b/src/fuzzing/UniValue__Read/input/round3.json new file mode 100644 index 000000000..7182dc2f9 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round3.json @@ -0,0 +1 @@ +"abcdefghijklmnopqrstuvwxyz" diff --git a/src/fuzzing/UniValue__Read/input/round4.json b/src/fuzzing/UniValue__Read/input/round4.json new file mode 100644 index 000000000..7f8f011eb --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round4.json @@ -0,0 +1 @@ +7 diff --git a/src/fuzzing/UniValue__Read/input/round5.json b/src/fuzzing/UniValue__Read/input/round5.json new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round5.json @@ -0,0 +1 @@ +true diff --git a/src/fuzzing/UniValue__Read/input/round6.json b/src/fuzzing/UniValue__Read/input/round6.json new file mode 100644 index 000000000..c508d5366 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round6.json @@ -0,0 +1 @@ +false diff --git a/src/fuzzing/UniValue__Read/input/round7.json b/src/fuzzing/UniValue__Read/input/round7.json new file mode 100644 index 000000000..19765bd50 --- /dev/null +++ b/src/fuzzing/UniValue__Read/input/round7.json @@ -0,0 +1 @@ +null diff --git a/zcutil/build.sh b/zcutil/build.sh index 23deda475..95ebd4e39 100755 --- a/zcutil/build.sh +++ b/zcutil/build.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -eu -o pipefail +set +x function cmd_pref() { if type -p "$2" > /dev/null; then @@ -69,6 +70,12 @@ as --version ld -v HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ + +if [ "${BUILD_STAGE:-all}" = "depends" ] +then + exit 0 +fi + ./autogen.sh CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure $CONFIGURE_FLAGS "$MAKE" "$@" diff --git a/zcutil/libfuzzer/libfuzzer-build.sh b/zcutil/libfuzzer/libfuzzer-build.sh new file mode 100755 index 000000000..3fdb4c465 --- /dev/null +++ b/zcutil/libfuzzer/libfuzzer-build.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +usage() { + echo "" + echo "$0 " + echo "" + echo "Build a fuzzer in the local repo using the following options:" + echo "" + echo ":" + echo " either \"depends\" or \"fuzzer\"" + echo "" + echo ":" + echo " -f,--fuzzer (ignored if building \"depends\")" + echo " [-s,--sanitizers ]" + echo " [-i,--instrument ]" + echo " [-l,--logfile ] # default is ./zcash-build-wrapper.log" + echo " [-h,--help]" + echo "" + echo "Where fuzzer is an entry in ./src/fuzzing/*, the default sanitizer" + echo "is \"address\" and default instrument is ( \"^.*/src/$\" )." + echo "" + exit -1 +} + +die() { + echo $1 + exit -1 +} + +# parse command line options + +POSITIONAL=() +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -f|--fuzzer) + FUZZER_NAME="$2" + if [ ! -f "./src/fuzzing/$FUZZER_NAME/fuzz.cpp" ] + then + die "Cannot find source code for fuzzer." + fi + shift + shift + ;; + -s|--sanitizers) + LLVM_SANITIZERS="$2" + shift + shift + ;; + -i|--instrument) + INSTRUMENT_CODE="$2" + shift + shift + ;; + -l|--logfile) + LOGFILE="$2" + shift + shift + ;; + -h|--help) + usage + shift + ;; + *) + POSITIONAL+=("$1") + shift + ;; +esac +done + +# positional arguments + +if [ ${#POSITIONAL[@]} -lt 1 ] +then + usage +else + BUILD_STAGE=${POSITIONAL[0]} +fi + +case "${BUILD_STAGE:-undefined}" in + depends) + FUZZER_NAME=notused + # fine + ;; + fuzzer) + # fine + ;; + *) + # not fine + usage + ;; +esac + +# required arguments + +if [ "${FUZZER_NAME:-undefined}" = "undefined" ] +then + usage +fi + +# default values + +if [ "${LLVM_SANITIZERS:-undefined}" = "undefined" ] +then + export LLVM_SANITIZERS="address" +fi +if [ "${INSTRUMENT_CODE:-undefined}" = "undefined" ] +then + export INSTRUMENT_CODE=("^.*\/src") +fi +if [ "${LOGFILE:-undefined}" = "undefined" ] +then + export LOGFILE=./zcash-build-wrapper.log +fi + +set -x + +export ZCUTIL=$(realpath "./zcutil") + +# overwrite the Linux make profile to use clang instead of GCC: + +cat $ZCUTIL/../depends/hosts/linux.mk | sed -e 's/=gcc/=clang/g' | sed -e 's/=g++/=clang++/g' > x +mv x $ZCUTIL/../depends/hosts/linux.mk + +# the build_stage distinction helps to layer an intermediate docker +# container for the built dependencies, so we can resume building +# from there assuming no other build arguments have changed + +if [ "$BUILD_STAGE" = "depends" ] +then + # make an empty fuzz file just so we can build dependencies + > src/fuzz.cpp +else + cp "./src/fuzzing/$FUZZER_NAME/fuzz.cpp" src/fuzz.cpp || die "Can't copy fuzz.cpp for that fuzzer" +fi + +# sneak the variable into zcashd's build.sh + +export BUILD_STAGE + +# run build.sh with our compiler wrapper, and BUILD_STAGE environment set: + +CONFIGURE_FLAGS="--enable-tests=no --disable-bench" \ + "$ZCUTIL/build.sh" \ + -j$(nproc) \ + "CC=$ZCUTIL/libfuzzer/zcash-wrapper-clang" \ + "CXX=$ZCUTIL/libfuzzer/zcash-wrapper-clang++" "${POSITIONAL[@]:1}" || die "Build failed at stage $BUILD_STAGE." diff --git a/zcutil/libfuzzer/zcash-wrapper b/zcutil/libfuzzer/zcash-wrapper new file mode 100755 index 000000000..8577ba764 --- /dev/null +++ b/zcutil/libfuzzer/zcash-wrapper @@ -0,0 +1,123 @@ +#!/usr/bin/env bash + +# you shouldn't normally be calling this script directly, it should be called +# by build.sh, but only when build.sh is invoked from libfuzzer-build.sh. + +set -ex -o pipefail + +# logging functions + +export green="\e[92m" +export red="\e[95m" +export normal="\e[0m" + +export color=$normal + +function log { + while read line + do + (echo ; echo -e "${color}${line}${normal}") >> "$LOGFILE" ; + done +} + +# command-line parsing + +export FINAL_LINK=0 # by default we using -fsanitize=fuzzer-no-link + +for arg do + shift + if [ "$arg" = "-fPIE" ] # no more pie + then + set -- "$@" "-fPIC" "-fno-pie" + continue + fi + if [ "$arg" = "-pie" ] + then + set -- "$@" "-no-pie" + continue + fi + if [ "$arg" = "-o" ] # here an output file is being specified + then + if [ "$1" = "zcashd" ] # here zcashd is the output file + then + export FINAL_LINK=1 # we should use -fsanitize=fuzzer because that links libfuzzer + fi + # note no continue, we fall through to default set + fi + set -- "$@" "$arg" +done + +# which source dirs to instrument + +if [ "$dirs_to_instrument" = "" ] +then + export dirs_to_instrument=("^.*\/src$") +fi + +# Store the command line we were given to a file + +echo "`hostname`:`pwd` \$" | log +echo -- "original command: $0 $@" | log + +# decide on a sanitizer option beyond just fuzzing: +# to link nor not to link libfuzzer we only link on +# the final call, to the linker. + +if [ "$LLVM_SANITIZE" = "" ] +then + export LLVM_SANITIZE="address" # you can override this behavior by setting this environment variable first +fi + +if [ "$FINAL_LINK" = "1" ] +then + export LLVM_SANITIZE="-fsanitize=fuzzer,$LLVM_SANITIZE" +else + export LLVM_SANITIZE="-fsanitize=fuzzer-no-link,$LLVM_SANITIZE" +fi + + +# Work out which compiler we were called as + +case $0 in +*zcash-wrapper-clang) + COMPILER="clang" + export DEFINES_FLAGS="${CFLAGS} -DZCASH_FUZZ=1 -DFUZZ_WITH_LIBFUZZER=1 -fPIC" + export INSTRUMENT_FLAGS="${DEFINES_FLAGS} ${LLVM_SANITIZE}" + ;; +*zcash-wrapper-clang++) + COMPILER="clang++" + export DEFINES_FLAGS="${CXXFLAGS} -DZCASH_FUZZ=1 -DFUZZ_WITH_LIBFUZZER=1 -fPIC" + export INSTRUMENT_FLAGS="${DEFINES_FLAGS} ${LLVM_SANITIZE}" + ;; +*zcash-wrapper) + echo -n "Call this script instead of your regular compiler, and if the absolute " + echo -n "path of the CWD the wrapper was called from matches a regex in the " + echo -n "array 'dirs_to_instrument', it will instrument the resulting object. " + echo -n "Otherwise it will exec directly to the original compiler without " + echo "changing arguments." + echo -n "You can also set LLVM_SANITIZE to whatever sanitizers you'd like to use." + echo -n "the default is 'address'. You don't need the -fsanitize=fuzzer part, " + echo "this script handles that" + exit + ;; +esac + +# Check if we should instrument + +for i in "${dirs_to_instrument[@]}" +do + if echo -- "`pwd`" | grep "$i"; then + # We found a match, let's instrument this one. + echo "pwd (`pwd`) matches dirs_to_instrument array element ($i). Adding instrumentation flags..." | log + echo "command with defines and instrumentation added:" | color=$green log + echo -- "$COMPILER" $INSTRUMENT_FLAGS "$@" | log + exec -- "$COMPILER" $INSTRUMENT_FLAGS "$@" + fi +done + +# No match, just pass-through. + +echo -e -- "${red}command with defines added:${normal}" | color=$red log +echo -- "$COMPILER" $DEFINES_FLAGS "$@" | log +exec -- "$COMPILER" $DEFINES_FLAGS "$@" + diff --git a/zcutil/libfuzzer/zcash-wrapper-clang b/zcutil/libfuzzer/zcash-wrapper-clang new file mode 120000 index 000000000..e640aa6e1 --- /dev/null +++ b/zcutil/libfuzzer/zcash-wrapper-clang @@ -0,0 +1 @@ +zcash-wrapper \ No newline at end of file diff --git a/zcutil/libfuzzer/zcash-wrapper-clang++ b/zcutil/libfuzzer/zcash-wrapper-clang++ new file mode 120000 index 000000000..e640aa6e1 --- /dev/null +++ b/zcutil/libfuzzer/zcash-wrapper-clang++ @@ -0,0 +1 @@ +zcash-wrapper \ No newline at end of file