Auto merge of #4547 - zebambam:add_libfuzzer_support, r=str4d

Add libfuzzer support

- Added libfuzzer support to the build system in zcutil.
- Added UniValue::Read fuzzer, dict, corpus.

I made a slight change to the build.sh script so as to separate dependency building vs src building, just so that I can layer the docker containers for building over in another repo to speed up the continuous build processes that will want to build multiple fuzzers from the same commit.

Closes #4548
This commit is contained in:
Homu 2020-08-12 20:47:53 +00:00
commit 9e117fdebe
68 changed files with 590 additions and 21 deletions

View File

@ -2,11 +2,43 @@
#include "chainparams.h" #include "chainparams.h"
#include "proof_verifier.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; int retval = 0;
if (!init_done) {
SelectParams(CBaseChainParams::MAIN); 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; CBlock block;
CAutoFile filein(fopen(argv[1], "rb"), SER_DISK, CLIENT_VERSION); CAutoFile filein(fopen(argv[1], "rb"), SER_DISK, CLIENT_VERSION);
try { try {
@ -14,17 +46,22 @@ int main (int argc, char *argv[]) {
} catch (const std::exception& e) { } catch (const std::exception& e) {
return -1; return -1;
} }
return fuzz_CheckBlock(block);
// 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;
} }
#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

View File

@ -1,10 +1,18 @@
#include <bits/stdc++.h>
#include <string>
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
// actual fuzzer
bool fuzz_DecodeHexTxFunction (const std::string& strHexTx) { bool fuzz_DecodeHexTxFunction (const std::string& strHexTx) {
CTransaction tx; CTransaction tx;
return DecodeHexTx(tx, strHexTx); return DecodeHexTx(tx, strHexTx);
} }
#ifdef FUZZ_WITH_AFL
// AFL
int fuzz_DecodeHexTx (int argc, char *argv[]) { int fuzz_DecodeHexTx (int argc, char *argv[]) {
std::ifstream t(argv[1]); 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); } 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

View File

@ -1,6 +1,9 @@
#include "addrman.h" #include "addrman.h"
#include "streams.h" #include "streams.h"
#ifdef FUZZ_WITH_AFL
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
CAddrMan addrman; CAddrMan addrman;
CAutoFile filein(fopen(argv[1], "rb"), SER_DISK, CLIENT_VERSION); CAutoFile filein(fopen(argv[1], "rb"), SER_DISK, CLIENT_VERSION);
@ -11,3 +14,20 @@ int main (int argc, char *argv[]) {
return -1; 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

View File

@ -1,3 +1,7 @@
#include <bits/stdc++.h>
// actual fuzzer
bool fuzz_TxDeserializeFunction (const std::vector<unsigned char> txData) { bool fuzz_TxDeserializeFunction (const std::vector<unsigned char> txData) {
CTransaction tx; CTransaction tx;
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
@ -9,6 +13,9 @@ bool fuzz_TxDeserializeFunction (const std::vector<unsigned char> txData) {
} }
} }
#ifdef FUZZ_WITH_AFL
// AFL
int fuzz_TxDeserialize (int argc, char *argv[]) { int fuzz_TxDeserialize (int argc, char *argv[]) {
std::ifstream t(argv[1]); 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); } 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<unsigned char> vect(Size);
memcpy(vect.data(), Data, Size);
fuzz_TxDeserializeFunction(vect);
return 0; // Non-zero return values are reserved for future use.
}
#endif

View File

@ -1,5 +1,7 @@
#include "txmempool.h" #include "txmempool.h"
#ifdef FUZZ_WITH_AFL
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
CFeeRate rate; CFeeRate rate;
CTxMemPool mempool(rate); CTxMemPool mempool(rate);
@ -11,3 +13,22 @@ int main (int argc, char *argv[]) {
return -1; 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

View File

@ -0,0 +1,7 @@
kw1="{"
kw2="}"
kw5="["
kw6="]"
kw7=":"
kw8=","
kw9="\""

View File

@ -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

View File

@ -0,0 +1 @@
"This is a string that never ends, yes it goes on and on, my friends.

View File

@ -0,0 +1 @@
{"Extra value after close": true} "misplaced quoted value"

View File

@ -0,0 +1 @@
{"Illegal expression": 1 + 2}

View File

@ -0,0 +1 @@
{"Illegal invocation": alert()}

View File

@ -0,0 +1 @@
{"Numbers cannot have leading zeroes": 013}

View File

@ -0,0 +1 @@
{"Numbers cannot be hex": 0x14}

View File

@ -0,0 +1 @@
["Illegal backslash escape: \x15"]

View File

@ -0,0 +1 @@
[\naked]

View File

@ -0,0 +1 @@
["Illegal backslash escape: \017"]

View File

@ -0,0 +1 @@
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]

View File

@ -0,0 +1 @@
{"Missing colon" null}

View File

@ -0,0 +1 @@
["Unclosed array"

View File

@ -0,0 +1 @@
{"Double colon":: null}

View File

@ -0,0 +1 @@
{"Comma instead of colon", null}

View File

@ -0,0 +1 @@
["Colon instead of comma": false]

View File

@ -0,0 +1 @@
["Bad value", truth]

View File

@ -0,0 +1 @@
['single quote']

View File

@ -0,0 +1 @@
[" tab character in string "]

View File

@ -0,0 +1 @@
["tab\ character\ in\ string\ "]

View File

@ -0,0 +1,2 @@
["line
break"]

View File

@ -0,0 +1,2 @@
["line\
break"]

View File

@ -0,0 +1 @@
[0e]

View File

@ -0,0 +1 @@
{unquoted_key: "keys must be quoted"}

View File

@ -0,0 +1 @@
[0e+]

View File

@ -0,0 +1 @@
[0e+-1]

View File

@ -0,0 +1 @@
{"Comma instead if closing brace": true,

View File

@ -0,0 +1 @@
["mismatch"}

View File

@ -0,0 +1 @@
{} garbage

View File

@ -0,0 +1 @@
[ true true true [] [] [] ]

View File

@ -0,0 +1 @@
{"a":}

View File

@ -0,0 +1 @@
{"a":1 "b":2}

View File

@ -0,0 +1 @@
["\ud834"]

View File

@ -0,0 +1 @@
["\udd61"]

View File

@ -0,0 +1 @@
["extra comma",]

View File

@ -0,0 +1 @@
["揣。"]

View File

@ -0,0 +1 @@
["<22><><EFBFBD>"]

Binary file not shown.

View File

@ -0,0 +1 @@
["double extra comma",,]

View File

@ -0,0 +1 @@
[ , "<-- missing value"]

View File

@ -0,0 +1 @@
["Comma after the close"],

View File

@ -0,0 +1 @@
["Extra close"]]

View File

@ -0,0 +1 @@
{"Extra comma": true,}

View File

@ -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": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\\\"\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"]

View File

@ -0,0 +1 @@
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]

View File

@ -0,0 +1,6 @@
{
"JSON Test Pattern pass3": {
"The outermost value": "must be an object or array.",
"In this test": "It is an object."
}
}

View File

@ -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"]

View File

@ -0,0 +1 @@
["a§■𐎒𝅘𝅥𝅯"]

View File

@ -0,0 +1 @@
"abcdefghijklmnopqrstuvwxyz"

View File

@ -0,0 +1 @@
7

View File

@ -0,0 +1 @@
true

View File

@ -0,0 +1 @@
false

View File

@ -0,0 +1 @@
null

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -exu -o pipefail
for d in src/fuzzing/*/ ; do for d in src/fuzzing/*/ ; do
fuzz_cases+="$(basename "$d"), " fuzz_cases+="$(basename "$d"), "

View File

@ -2,7 +2,6 @@
set -ex -o pipefail set -ex -o pipefail
export ARGS=$@
instrument=( instrument=(
"\/src$" "\/src$"
@ -22,10 +21,22 @@ fi
case $0 in case $0 in
*zcash-wrapper-g++) *zcash-wrapper-g++)
COMPILER="g++" OCOMPILER="g++"
ACOMPILER=$OCOMPILER
;; ;;
*zcash-wrapper-gcc) *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) *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." 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 if echo -- "`pwd`" | grep "$i"; then
# We found a match, let's instrument this one. # 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" 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 fi
done done
# No match, just pass-through. # No match, just pass-through.
exec -- "$COMPILER" "$@" exec -- "$OCOMPILER" "$@"

View File

@ -0,0 +1 @@
zcash-wrapper

View File

@ -0,0 +1 @@
zcash-wrapper

View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu -o pipefail set -eu -o pipefail
set +x
function cmd_pref() { function cmd_pref() {
if type -p "$2" > /dev/null; then if type -p "$2" > /dev/null; then
@ -69,6 +70,12 @@ as --version
ld -v ld -v
HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/
if [ "${BUILD_STAGE:-all}" = "depends" ]
then
exit 0
fi
./autogen.sh ./autogen.sh
CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure $CONFIGURE_FLAGS CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure $CONFIGURE_FLAGS
"$MAKE" "$@" "$MAKE" "$@"

View File

@ -0,0 +1,151 @@
#!/usr/bin/env bash
set -eu -o pipefail
usage() {
echo ""
echo "$0 <build stage> <options> <passthrough build arguments>"
echo ""
echo "Build a fuzzer in the local repo using the following options:"
echo ""
echo "<build stage>:"
echo " either \"depends\" or \"fuzzer\""
echo ""
echo "<options>:"
echo " -f,--fuzzer <fuzzername> (ignored if building \"depends\")"
echo " [-s,--sanitizers <sanitizers>]"
echo " [-i,--instrument <instrument>]"
echo " [-l,--logfile <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."

123
zcutil/libfuzzer/zcash-wrapper Executable file
View File

@ -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 "$@"

View File

@ -0,0 +1 @@
zcash-wrapper

View File

@ -0,0 +1 @@
zcash-wrapper