diff options
| author | mtg0001 <106211915+mtg0001@users.noreply.github.com> | 2026-08-04 15:31:55 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-04 15:31:55 -0300 |
| commit | b3a5a858e536acf65e6c6761293626628f2227bf (patch) | |
| tree | 881dbe44ac6c0ea28f5a65cbfd9b835ba73ea648 /src/fuzz_net_message.cpp | |
| parent | 173b4649e90f4f5ba49e92569eb063709e647c7d (diff) | |
fuzz: add P2P message parser harness (#142)
* fuzz: add P2P message parser harness
* fuzz: avoid duplicate legacy header includes
* fuzz: seed the corpus with our network magic, not Bitcoin's
The two seed inputs began f5 be b6 d9, which is Bitcoin's message
start. Ours is bf 20 5c fd. CMessageHeader::IsValid rejects on that
field first, so both seeds died at the first check and the smoke run
exercised the reject path and nothing else.
libFuzzer would have to mutate its way onto four exact bytes before
reaching any parser, which does not happen in 128 runs. The job would
have gone green while covering none of what it was added to cover.
---------
Co-authored-by: Gilcimar Duarte <ti@gpm.infra>
Co-authored-by: Bitflash-sh <btf01@proton.me>
Diffstat (limited to 'src/fuzz_net_message.cpp')
| -rw-r--r-- | src/fuzz_net_message.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/fuzz_net_message.cpp b/src/fuzz_net_message.cpp new file mode 100644 index 0000000..1104d90 --- /dev/null +++ b/src/fuzz_net_message.cpp | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // libFuzzer harness for the P2P message envelope parser. It feeds arbitrary | ||
| 5 | // receive-buffer bytes into ProcessMessages() through a dummy CNode, without | ||
| 6 | // opening sockets or starting node threads. | ||
| 7 | |||
| 8 | #include "headers_core.h" | ||
| 9 | |||
| 10 | #include <stdint.h> | ||
| 11 | #include <stddef.h> | ||
| 12 | |||
| 13 | // Stand-ins normally supplied by the GUI/headless entry objects. | ||
| 14 | map<string,string> mapAddressBook; | ||
| 15 | bool gPoolServerRunning = false; | ||
| 16 | void MainFrameRepaint() {} | ||
| 17 | |||
| 18 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) | ||
| 19 | { | ||
| 20 | // Keep this first target focused on parser behavior, not multi-megabyte | ||
| 21 | // allocation pressure. The protocol size guards have their own selftest. | ||
| 22 | if (size > 4096) | ||
| 23 | return 0; | ||
| 24 | |||
| 25 | CNode node(INVALID_SOCKET, CAddress("127.0.0.1")); | ||
| 26 | node.nVersion = 0; // exercise pre-version gating plus the version parser | ||
| 27 | if (size > 0) | ||
| 28 | node.vRecv.write((const char*)data, (int)size); | ||
| 29 | |||
| 30 | ProcessMessages(&node); | ||
| 31 | return 0; | ||
| 32 | } | ||