Skip to content

Conversation

@practicalswift
Copy link
Contributor

Add RPC interface fuzzing.

This PR increases overall fuzzing line coverage from ~65% to ~70% 🎉

To test this PR:

$ make distclean
$ ./autogen.sh
$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
$ make -C src/ test/fuzz/fuzz
$ FUZZ=rpc src/test/fuzz/fuzz

See doc/fuzzing.md for more information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the Bitcoin Core fuzzing corpus repo.

Happy fuzzing :)

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK, debug build clean and it runs

$ FUZZ=rpc src/test/fuzz/fuzz
INFO: Seed: 974835892
INFO: Loaded 1 modules   (625697 inline 8-bit counters): 625697 [0x5636dc7b9268, 0x5636dc851e89), 
INFO: Loaded 1 PC tables (625697 PCs): 625697 [0x5636dc851e90,0x5636dd1de0a0), 
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2	INITED cov: 110 ft: 111 corp: 1/1b exec/s: 0 rss: 191Mb
#4	NEW    cov: 110 ft: 118 corp: 2/3b lim: 4 exec/s: 0 rss: 191Mb L: 2/2 MS: 2 ChangeBit-InsertByte-
#10	NEW    cov: 110 ft: 125 corp: 3/6b lim: 4 exec/s: 0 rss: 191Mb L: 3/3 MS: 1 CopyPart-
#13	NEW    cov: 110 ft: 130 corp: 4/10b lim: 4 exec/s: 0 rss: 191Mb L: 4/4 MS: 3 ChangeBinInt-EraseBytes-CrossOver-
...
#217864	REDUCE cov: 16595 ft: 45707 corp: 992/59Kb lim: 116 exec/s: 1998 rss: 616Mb L: 84/116 MS: 1 EraseBytes-
#218080	REDUCE cov: 16595 ft: 45709 corp: 993/59Kb lim: 116 exec/s: 2000 rss: 616Mb L: 115/116 MS: 1 InsertRepeatedBytes-
#218133	REDUCE cov: 16595 ft: 45709 corp: 993/59Kb lim: 116 exec/s: 2001 rss: 616Mb L: 84/116 MS: 3 ChangeByte-CMP-EraseBytes- DE: "St9exception"-
	NEW_FUNC[1/25]: 0x5636d8897d20 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h:152
	NEW_FUNC[2/25]: 0x5636d88db840 in std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<CBlock, std::allocator<CBlock>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<CBlock, std::allocator<CBlock>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<CBlock, std::allocator<CBlock>, (__gnu_cxx::_Lock_policy)2> >&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/allocated_ptr.h:96
#218742	REDUCE cov: 16767 ft: 45872 corp: 994/59Kb lim: 122 exec/s: 1988 rss: 616Mb L: 30/116 MS: 4 EraseBytes-ChangeBit-ChangeBinInt-CMP- DE: "submitblock"-

@maflcko
Copy link
Member

maflcko commented Feb 22, 2021

I am not sure if this is worth it. This needs a lot of maintenance (adding or removing rpcs, marking them unsafe, ...) and I am sceptical that this will find any actual issues.

@adamjonas
Copy link
Member

@MarcoFalke to clarify, are you a NACK on this?

@practicalswift
Copy link
Contributor Author

practicalswift commented Apr 27, 2021

@adamjonas

Good question and thanks for asking it explicitly! :)

I should probably have stated that more clearly in the PR description, but it should be noted that this fuzzing harness is by far is the "most covering" harness in the repo.

Including this harness in the existing set of fuzzing harnesses adds coverage to five(!) percent of the code base that is currently uncovered by fuzz testing. The total fuzzing coverage increases from 65% to 70%.

The opportunities to achieve such extreme coverage jumps from adding a single harness are extremely rare at the relatively high levels of fuzzing coverage we've reached. TBH it would feel a bit disappointing if we had to pass on the excellent coverage opportunity that RPC fuzzing brings :)

@MarcoFalke, if we can find a way to reduce/mitigate the potential maintenance work you predict in #21169 (comment) would you be willing to reconsider your position? :)

@maflcko
Copy link
Member

maflcko commented Apr 28, 2021

Concept ACK 545404e

If this is leading to too much (maintenance) hassle, it can be reverted.

@maflcko maflcko merged commit e458631 into bitcoin:master Apr 28, 2021
"dumpwallet", // avoid writing to disk
#endif
"echoipc", // avoid assertion failure (Assertion `"EnsureAnyNodeContext(request.context).init" && check' failed.)
"generatetoaddress", // avoid timeout
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this unsafe, but the other generate* calls are safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Addressed in #21810:

    "generatetoaddress",    // avoid prohibitively slow execution (when `num_blocks` is large)
    "generatetodescriptor", // avoid prohibitively slow execution (when `nblocks` is large)

// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <base58.h>
#include <chainparamsbase.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Addressed in follow-up.

#include <base58.h>
#include <chainparamsbase.h>
#include <core_io.h>
#include <interfaces/chain.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Addressed in follow-up.

"importwallet", // avoid reading from disk
"loadwallet", // avoid reading from disk
#endif
"mockscheduler", // avoid assertion failure (Assertion `delta_seconds.count() > 0 && delta_seconds < std::chrono::hours{1}' failed.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems so! Thanks! Re-enabled in follow-up.

"preciousblock",
"pruneblockchain",
"reconsiderblock",
"savemempool",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems dangerous. If the rpc is ever changed to take a file path, how would we know to adjust this line?

Copy link
Contributor Author

@practicalswift practicalswift Apr 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Disabled as a precautionary measure in #21810.

dump*, save*, import* and load* commands should probably not be part of RPC_COMMANDS_SAFE_FOR_FUZZING.

Longer term we could perhaps also find a clever way to annotate/auto-detect RPC commands with file path arguments and have them automatically removed from RPC_COMMANDS_SAFE_FOR_FUZZING if they are incorrectly included there for some reason. Belts and suspenders! :)

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 28, 2021
…g coverage from 65% to 70%.

545404e fuzz: Add RPC interface fuzzing. Increase fuzzing coverage from 65% to 70%. (practicalswift)

Pull request description:

  Add RPC interface fuzzing.

  This PR increases overall fuzzing line coverage from [~65%](https://marcofalke.github.io/btc_cov/fuzz.coverage/) to ~70% 🎉

  To test this PR:

  ```
  $ make distclean
  $ ./autogen.sh
  $ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
  $ make -C src/ test/fuzz/fuzz
  $ FUZZ=rpc src/test/fuzz/fuzz
  ```

  See [`doc/fuzzing.md`](https://github.com/bitcoin/bitcoin/blob/master/doc/fuzzing.md) for more information on how to fuzz Bitcoin Core. Don't forget to contribute any coverage increasing inputs you find to the [Bitcoin Core fuzzing corpus repo](https://github.com/bitcoin-core/qa-assets).

  Happy fuzzing :)

ACKs for top commit:
  MarcoFalke:
    Concept ACK 545404e

Tree-SHA512: 35fc1b508af42bf480ee3762326b09ff2eecdb7960a1917ad16345fadd5c0c21d666dafe736176e5a848ff6492483c782e4ea914cd9000faf50190df051950fd
maflcko pushed a commit to bitcoin-core/gui that referenced this pull request May 3, 2021
5252f86 fuzz: Reduce maintenance requirements by allowing RPC annotations also for conditionally available RPC commands (such as wallet commands) without the fragility of #ifdef forests (practicalswift)
54549dd fuzz: RPC fuzzer post-merge follow-ups. Remove unused includes. Update list of fuzzed RPC commands. (practicalswift)

Pull request description:

  Various RPC fuzzer follow-ups:
  * Remove unused includes.
  * Update list of fuzzed RPC commands.
  * Reduce maintenance requirements by allowing RPC annotations also for conditionally available RPC commands (such as wallet commands) without the fragility of `#ifdef` forests.

  Context: bitcoin/bitcoin#21169 (review)

ACKs for top commit:
  MarcoFalke:
    Concept ACK 5252f86

Tree-SHA512: 286d70798131706ffb157758e1c73f7f00ed96ce120c7d9dc849e672b283f1362df47b206cfec9da44d5debb5869225e721761dcd5c38a7d5d1019dc6c912ab2
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 3, 2021
5252f86 fuzz: Reduce maintenance requirements by allowing RPC annotations also for conditionally available RPC commands (such as wallet commands) without the fragility of #ifdef forests (practicalswift)
54549dd fuzz: RPC fuzzer post-merge follow-ups. Remove unused includes. Update list of fuzzed RPC commands. (practicalswift)

Pull request description:

  Various RPC fuzzer follow-ups:
  * Remove unused includes.
  * Update list of fuzzed RPC commands.
  * Reduce maintenance requirements by allowing RPC annotations also for conditionally available RPC commands (such as wallet commands) without the fragility of `#ifdef` forests.

  Context: bitcoin#21169 (review)

ACKs for top commit:
  MarcoFalke:
    Concept ACK 5252f86

Tree-SHA512: 286d70798131706ffb157758e1c73f7f00ed96ce120c7d9dc849e672b283f1362df47b206cfec9da44d5debb5869225e721761dcd5c38a7d5d1019dc6c912ab2
gwillen pushed a commit to ElementsProject/elements that referenced this pull request Jun 1, 2022
Adds fuzztests for RPC. FIXME there is a crash; I just disabled the
test for now and we can revisit in a future PR.
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants