HomePhabricator

[backport#17009] tests: Add EvalScript(...) fuzzing harness

Description

[backport#17009] tests: Add EvalScript(...) fuzzing harness

Summary:
7e50abcc29dc5fde24a1b3e57c6316eabda35e2e tests: Add EvalScript(...) fuzzing harness (practicalswift)
bebb637472d0469037a9f438572fc71db4236d97 tests: Add FuzzedDataProvider fuzzing helper from the Chromium project (practicalswift)

Pull request description:

Add `EvalScript(...)` fuzzing harness.

To test this PR:

We can run `contrib/devtools/test_fuzzing_harnesses.sh` (#17000) during five seconds to quickly verify that the newly added  fuzz harness seem to hit relevant code regions, that the fuzzing throughput seems reasonable, etc.

`test_fuzzing_harnesses.sh eval 5` runs all fuzzers matching the regexp `eval` giving them five seconds of runtime each.

```
$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
$ make
$ contrib/devtools/test_fuzzing_harnesses.sh eval 5
Testing fuzzer eval_script during 5 second(s)
A subset of reached functions:
        NEW_FUNC[1/24]: 0x557b808742e0 in prevector<28u, unsigned char, unsigned int, int>::indirect_ptr(int) src/./prevector.h:161
        NEW_FUNC[2/24]: 0x557b80875460 in prevector<28u, unsigned char, unsigned int, int>::indirect_ptr(int) const src/./prevector.h:162
        NEW_FUNC[6/9]: 0x557b81acdaa0 in popstack(std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&) src/script/interpreter.cpp:57
        NEW_FUNC[5/16]: 0x557b809f1bf0 in CScriptNum::serialize(long const&) src/./script/script.h:326
        NEW_FUNC[4/6]: 0x557b817c93d0 in CScriptNum::CScriptNum(std::vector<unsigned char, std::allocator<unsigned char> > const&, bool, unsigned long) src/./script/script.h:225
        NEW_FUNC[5/6]: 0x557b817cbb80 in CScriptNum::set_vch(std::vector<unsigned char, std::allocator<unsigned char> > const&) src/./script/script.h:360
        NEW_FUNC[0/11]: 0x557b80a88170 in CHash256::Write(unsigned char const*, unsigned long) src/./hash.h:34
        NEW_FUNC[1/11]: 0x557b80a88270 in CHash256::Finalize(unsigned char*) src/./hash.h:28
        NEW_FUNC[5/11]: 0x557b81affdb0 in CSHA256::CSHA256() src/crypto/sha256.cpp:644
        NEW_FUNC[6/11]: 0x557b81affe80 in (anonymous namespace)::sha256::Initialize(unsigned int*) src/crypto/sha256.cpp:66
        NEW_FUNC[7/11]: 0x557b81b00460 in CSHA256::Write(unsigned char const*, unsigned long) src/crypto/sha256.cpp:649
        NEW_FUNC[8/11]: 0x557b81b009a0 in CSHA256::Finalize(unsigned char*) src/crypto/sha256.cpp:675
        NEW_FUNC[9/11]: 0x557b81b015e0 in CSHA256::Reset() src/crypto/sha256.cpp:692
        NEW_FUNC[10/11]: 0x557b81b01d90 in (anonymous namespace)::sha256::Transform(unsigned int*, unsigned char const*, unsigned long) src/crypto/sha256.cpp:79
        NEW_FUNC[0/1]: 0x557b808cc180 in BaseSignatureChecker::CheckLockTime(CScriptNum const&) const src/./script/interpreter.h:153
        NEW_FUNC[0/2]: 0x557b81ab5640 in CastToBool(std::vector<unsigned char, std::allocator<unsigned char> > const&) src/script/interpreter.cpp:36
        NEW_FUNC[0/1]: 0x557b817c9c30 in CScriptNum::getint() const src/./script/script.h:312
        NEW_FUNC[0/1]: 0x557b81ae1df0 in CScriptNum::operator-=(long const&) src/./script/script.h:298
        NEW_FUNC[0/5]: 0x557b81af5670 in CRIPEMD160::CRIPEMD160() src/crypto/ripemd160.cpp:243
        NEW_FUNC[1/5]: 0x557b81af5740 in (anonymous namespace)::ripemd160::Initialize(unsigned int*) src/crypto/ripemd160.cpp:25
        NEW_FUNC[2/5]: 0x557b81af5b00 in CRIPEMD160::Write(unsigned char const*, unsigned long) src/crypto/ripemd160.cpp:248
        NEW_FUNC[3/5]: 0x557b81af5fa0 in (anonymous namespace)::ripemd160::Transform(unsigned int*, unsigned char const*) src/crypto/ripemd160.cpp:55
        NEW_FUNC[4/5]: 0x557b81af8d60 in CRIPEMD160::Finalize(unsigned char*) src/crypto/ripemd160.cpp:274
        NEW_FUNC[0/16]: 0x557b80857a30 in CScript::operator<<(std::vector<unsigned char, std::allocator<unsigned char> > const&) src/./script/script.h:462
        NEW_FUNC[1/16]: 0x557b80872670 in prevector<28u, unsigned char, unsigned int, int>::insert(prevector<28u, unsigned char, unsigned int, int>::iterator, unsigned char const&) src/./prevector.h:342
        NEW_FUNC[2/16]: 0x557b80872e00 in void prevector<28u, unsigned char, unsigned int, int>::insert<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > >(prevector<28u, unsigned char, unsigned int, int>::iterator, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > >) src/./prevector.h:368
        NEW_FUNC[3/16]: 0x557b80873630 in prevector<28u, unsigned char, unsigned int, int>::capacity() const src/./prevector.h:295
        NEW_FUNC[4/16]: 0x557b80874ed0 in void prevector<28u, unsigned char, unsigned int, int>::fill<prevector<28u, unsigned char, unsigned int, int>::const_iterator>(unsigned char*, prevector<28u, unsigned char, unsigned int, int>::const_iterator, prevector<28u, unsigned char, unsigned int, int>::const_iterator) src/./prevector.h:204
        NEW_FUNC[5/16]: 0x557b808cc0f0 in BaseSignatureChecker::CheckSig(std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, CScript const&, SigVersion) const src/./script/interpreter.h:148
        NEW_FUNC[6/16]: 0x557b809edb10 in CScript::operator=(CScript&&) src/./script/script.h:390
        NEW_FUNC[7/16]: 0x557b809f8ec0 in void prevector<28u, unsigned char, unsigned int, int>::insert<prevector<28u, unsigned char, unsigned int, int>::const_iterator>(prevector<28u, unsigned char, unsigned int, int>::iterator, prevector<28u, unsigned char, unsigned int, int>::const_iterator, prevector<28u, unsigned char, unsigned int, int>::const_iterator) src/./prevector.h:368
        NEW_FUNC[8/16]: 0x557b809f9260 in prevector<28u, unsigned char, unsigned int, int>::swap(prevector<28u, unsigned char, unsigned int, int>&) src/./prevector.h:451
        NEW_FUNC[9/16]: 0x557b81ab58c0 in CheckSignatureEncoding(std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned int, ScriptError_t*) src/script/interpreter.cpp:200
        NEW_FUNC[10/16]: 0x557b81ab6f30 in FindAndDelete(CScript&, CScript const&) src/script/interpreter.cpp:254
        NEW_FUNC[11/16]: 0x557b81acdc20 in CheckPubKeyEncoding(std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned int, SigVersion const&, ScriptError_t*) src/script/interpreter.cpp:217
        NEW_FUNC[12/16]: 0x557b81ad3890 in IsCompressedOrUncompressedPubKey(std::vector<unsigned char, std::allocator<unsigned char> > const&) src/script/interpreter.cpp:63
        NEW_FUNC[13/16]: 0x557b81ad8830 in CScript::GetOp(prevector<28u, unsigned char, unsigned int, int>::const_iterator&, opcodetype&) const src/./script/script.h:505
        NEW_FUNC[14/16]: 0x557b81ae21a0 in prevector<28u, unsigned char, unsigned int, int>::prevector<prevector<28u, unsigned char, unsigned int, int>::const_iterator>(prevector<28u, unsigned char, unsigned int, int>::const_iterator, prevector<28u, unsigned char, unsigned int, int>::const_iterator) src/./prevector.h:246
        NEW_FUNC[0/1]: 0x557b81ae1a40 in CScriptNum::operator+=(long const&) src/./script/script.h:290
        NEW_FUNC[0/5]: 0x557b81af9760 in CSHA1::CSHA1() src/crypto/sha1.cpp:150
        NEW_FUNC[1/5]: 0x557b81af9830 in (anonymous namespace)::sha1::Initialize(unsigned int*) src/crypto/sha1.cpp:32
        NEW_FUNC[2/5]: 0x557b81af9bf0 in CSHA1::Write(unsigned char const*, unsigned long) src/crypto/sha1.cpp:155
        NEW_FUNC[3/5]: 0x557b81afa090 in (anonymous namespace)::sha1::Transform(unsigned int*, unsigned char const*) src/crypto/sha1.cpp:47
        NEW_FUNC[4/5]: 0x557b81afc5e0 in CSHA1::Finalize(unsigned char*) src/crypto/sha1.cpp:181
        NEW_FUNC[0/1]: 0x557b81ada4f0 in CScriptNum::operator-() const src/./script/script.h:278
        NEW_FUNC[0/1]: 0x557b808cc210 in BaseSignatureChecker::CheckSequence(CScriptNum const&) const src/./script/interpreter.h:158
        NEW_FUNC[0/1]: 0x557b81ab5c00 in IsValidSignatureEncoding(std::vector<unsigned char, std::allocator<unsigned char> > const&) src/script/interpreter.cpp:107
stat::number_of_executed_units: 9728
stat::average_exec_per_sec:     1621
stat::new_units_added:          844
stat::slowest_unit_time_sec:    0
stat::peak_rss_mb:              326
Number of unique code paths taken during fuzzing round: 583

Tested fuzz harnesses seem to work as expected.
```

Depends on D6744

Backport of Core PR17009

Test Plan:

export CC=clang CXX=clang++
../configure --enable-fuzz --with-sanitizers=fuzzer,address \
  --disable-wallet \
  --disable-bench \
  --with-utils=no \
  --with-daemon=no \
  --with-libs=no \
  --with-gui=no \
  --with-seeder=no
make
mkdir -p test/fuzz
cp ../test/fuzz/test_runner.py test/fuzz/
./test/fuzz/test_runner.py -l DEBUG <path_to_corpus>

cmake -GNinja .. -DENABLE_SANITIZERS="address;fuzzer" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
ninja bitcoin-fuzzers link-fuzz-test_runner.py
./test/fuzz/test_runner.py -l DEBUG <path_to_corpus>

Reviewers: #bitcoin_abc, deadalnix

Reviewed By: #bitcoin_abc, deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D6745

Details

Provenance
MarcoFalke <falke.marco@gmail.com>Authored on Oct 14 2019, 13:27
majcostaCommitted on Jul 1 2020, 19:43
majcostaPushed on Jul 1 2020, 19:43
Reviewer
Restricted Project
Differential Revision
D6745: [backport#17009] tests: Add EvalScript(...) fuzzing harness
Parents
rABC4d8a91846647: [linter] add exceptions to include guards and file name linters
Branches
Unknown
Tags
Unknown