Skip to content

Commit fd0be92

Browse files
doc: Add instructions on how to fuzz the P2P layer using Honggfuzz NetDriver
1 parent 0bd4929 commit fd0be92

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

doc/fuzzing.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,77 @@ $ honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/process_message
157157
```
158158
159159
Read the [Honggfuzz documentation](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more information.
160+
161+
## Fuzzing the Bitcoin Core P2P layer using Honggfuzz NetDriver
162+
163+
Honggfuzz NetDriver allows for very easy fuzzing of TCP servers such as Bitcoin
164+
Core without having to write any custom fuzzing harness. The `bitcoind` server
165+
process is largely fuzzed without modification.
166+
167+
This makes the fuzzing highly realistic: a bug reachable by the fuzzer is likely
168+
also remotely triggerable by an untrusted peer.
169+
170+
To quickly get started fuzzing the P2P layer using Honggfuzz NetDriver:
171+
172+
```sh
173+
$ mkdir bitcoin-honggfuzz-p2p/
174+
$ cd bitcoin-honggfuzz-p2p/
175+
$ git clone https://github.com/bitcoin/bitcoin
176+
$ cd bitcoin/
177+
$ ./autogen.sh
178+
$ git clone https://github.com/google/honggfuzz
179+
$ cd honggfuzz/
180+
$ make
181+
$ cd ..
182+
$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang \
183+
CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ \
184+
./configure --disable-wallet --with-gui=no \
185+
--with-sanitizers=address,undefined
186+
$ git apply << "EOF"
187+
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
188+
index 455a82e39..2faa3f80f 100644
189+
--- a/src/bitcoind.cpp
190+
+++ b/src/bitcoind.cpp
191+
@@ -158,7 +158,11 @@ static bool AppInit(int argc, char* argv[])
192+
return fRet;
193+
}
194+
195+
+#ifdef HFND_FUZZING_ENTRY_FUNCTION_CXX
196+
+HFND_FUZZING_ENTRY_FUNCTION_CXX(int argc, char* argv[])
197+
+#else
198+
int main(int argc, char* argv[])
199+
+#endif
200+
{
201+
#ifdef WIN32
202+
util::WinCmdLineArgs winArgs;
203+
diff --git a/src/net.cpp b/src/net.cpp
204+
index cf987b699..636a4176a 100644
205+
--- a/src/net.cpp
206+
+++ b/src/net.cpp
207+
@@ -709,7 +709,7 @@ int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
208+
}
209+
210+
// Check start string, network magic
211+
- if (memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) {
212+
+ if (false && memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) { // skip network magic checking
213+
LogPrint(BCLog::NET, "HEADER ERROR - MESSAGESTART (%s, %u bytes), received %s, peer=%d\n", hdr.GetCommand(), hdr.nMessageSize, HexStr(hdr.pchMessageStart), m_node_id);
214+
return -1;
215+
}
216+
@@ -768,7 +768,7 @@ Optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::mic
217+
RandAddEvent(ReadLE32(hash.begin()));
218+
219+
// Check checksum and header command string
220+
- if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
221+
+ if (false && memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) { // skip checksum checking
222+
LogPrint(BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s, peer=%d\n",
223+
SanitizeString(msg->m_command), msg->m_message_size,
224+
HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
225+
EOF
226+
$ make -C src/ bitcoind
227+
$ mkdir -p inputs/
228+
$ honggfuzz/honggfuzz --exit_upon_crash --quiet --timeout 4 -n 1 -Q \
229+
-E HFND_TCP_PORT=18444 -f inputs/ -- \
230+
src/bitcoind -regtest -discover=0 -dns=0 -dnsseed=0 -listenonion=0 \
231+
-nodebuglogfile -bind=127.0.0.1:18444 -logthreadnames \
232+
-debug
233+
```

0 commit comments

Comments
 (0)