aboutsummaryrefslogtreecommitdiff
path: root/doc/fuzzing.md
diff options
context:
space:
mode:
authorpracticalswift <practicalswift@users.noreply.github.com>2020-11-12 20:01:32 +0000
committerpracticalswift <practicalswift@users.noreply.github.com>2020-11-12 20:20:29 +0000
commitfd0be92cff6a4b5e343e6ddae7481868354b9869 (patch)
tree524db7cd338a0b04c83cf391f93b99cf1c4329aa /doc/fuzzing.md
parent0bd4929cd00e91bf4137f43b097cd62f72f503e4 (diff)
downloadbitcoin-fd0be92cff6a4b5e343e6ddae7481868354b9869.tar.xz
doc: Add instructions on how to fuzz the P2P layer using Honggfuzz NetDriver
Diffstat (limited to 'doc/fuzzing.md')
-rw-r--r--doc/fuzzing.md74
1 files changed, 74 insertions, 0 deletions
diff --git a/doc/fuzzing.md b/doc/fuzzing.md
index c97b8d4d50..4391fb78a2 100644
--- a/doc/fuzzing.md
+++ b/doc/fuzzing.md
@@ -157,3 +157,77 @@ $ honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/process_message
```
Read the [Honggfuzz documentation](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more information.
+
+## Fuzzing the Bitcoin Core P2P layer using Honggfuzz NetDriver
+
+Honggfuzz NetDriver allows for very easy fuzzing of TCP servers such as Bitcoin
+Core without having to write any custom fuzzing harness. The `bitcoind` server
+process is largely fuzzed without modification.
+
+This makes the fuzzing highly realistic: a bug reachable by the fuzzer is likely
+also remotely triggerable by an untrusted peer.
+
+To quickly get started fuzzing the P2P layer using Honggfuzz NetDriver:
+
+```sh
+$ mkdir bitcoin-honggfuzz-p2p/
+$ cd bitcoin-honggfuzz-p2p/
+$ git clone https://github.com/bitcoin/bitcoin
+$ cd bitcoin/
+$ ./autogen.sh
+$ git clone https://github.com/google/honggfuzz
+$ cd honggfuzz/
+$ make
+$ cd ..
+$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang \
+ CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ \
+ ./configure --disable-wallet --with-gui=no \
+ --with-sanitizers=address,undefined
+$ git apply << "EOF"
+diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
+index 455a82e39..2faa3f80f 100644
+--- a/src/bitcoind.cpp
++++ b/src/bitcoind.cpp
+@@ -158,7 +158,11 @@ static bool AppInit(int argc, char* argv[])
+ return fRet;
+ }
+
++#ifdef HFND_FUZZING_ENTRY_FUNCTION_CXX
++HFND_FUZZING_ENTRY_FUNCTION_CXX(int argc, char* argv[])
++#else
+ int main(int argc, char* argv[])
++#endif
+ {
+ #ifdef WIN32
+ util::WinCmdLineArgs winArgs;
+diff --git a/src/net.cpp b/src/net.cpp
+index cf987b699..636a4176a 100644
+--- a/src/net.cpp
++++ b/src/net.cpp
+@@ -709,7 +709,7 @@ int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
+ }
+
+ // Check start string, network magic
+- if (memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) {
++ if (false && memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) { // skip network magic checking
+ LogPrint(BCLog::NET, "HEADER ERROR - MESSAGESTART (%s, %u bytes), received %s, peer=%d\n", hdr.GetCommand(), hdr.nMessageSize, HexStr(hdr.pchMessageStart), m_node_id);
+ return -1;
+ }
+@@ -768,7 +768,7 @@ Optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::mic
+ RandAddEvent(ReadLE32(hash.begin()));
+
+ // Check checksum and header command string
+- if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
++ if (false && memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) { // skip checksum checking
+ LogPrint(BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s, peer=%d\n",
+ SanitizeString(msg->m_command), msg->m_message_size,
+ HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
+EOF
+$ make -C src/ bitcoind
+$ mkdir -p inputs/
+$ honggfuzz/honggfuzz --exit_upon_crash --quiet --timeout 4 -n 1 -Q \
+ -E HFND_TCP_PORT=18444 -f inputs/ -- \
+ src/bitcoind -regtest -discover=0 -dns=0 -dnsseed=0 -listenonion=0 \
+ -nodebuglogfile -bind=127.0.0.1:18444 -logthreadnames \
+ -debug
+```