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