fuzz: Add IPC round-trip fuzz target #35118

pull enirox001 wants to merge 3 commits into bitcoin:master from enirox001:fuzz-ipc-initial changing 7 files +191 −14
  1. enirox001 commented at 8:30 AM on April 20, 2026: contributor

    <!-- *** Please remove the following help text before submitting: *** Pull requests without a rationale and clear improvement may be closed immediately. GUI-related pull requests should be opened against https://github.com/bitcoin-core/gui first. See CONTRIBUTING.md -->

    <!-- Please provide clear motivation for your patch and explain how it improves Bitcoin Core user experience or Bitcoin Core developer experience significantly: * Any test improvements or new tests that improve coverage are always welcome. * All other changes should have accompanying unit tests (see `src/test/`) or functional tests (see `test/`). Contributors should note which tests cover modified code. If no tests exist for a region of modified code, new tests should accompany the change. * Bug fixes are most welcome when they come with steps to reproduce or an explanation of the potential issue as well as reasoning for the way the bug was fixed. * Features are welcome, but might be rejected due to design or scope issues. If a feature is based on a lot of dependencies, contributors should first consider building the system outside of Bitcoin Core, if possible. * Refactoring changes are only accepted if they are required for a feature or bug fix or otherwise improve developer experience significantly. For example, most "code style" refactoring changes require a thorough explanation why they are useful, what downsides they have and why they *significantly* improve developer experience or avoid serious programming bugs. Note that code style is often a subjective matter. Unless they are explicitly mentioned to be preferred in the [developer notes](/doc/developer-notes.md), stylistic code changes are usually rejected. -->

    <!-- Bitcoin Core has a thorough review process and even the most trivial change needs to pass a lot of eyes and requires non-zero or even substantial time effort to review. There is a huge lack of active reviewers on the project, so patches often sit for a long time. -->

    As discussed in #23015, adding fuzz coverage for the IPC layer is important for ensuring the memory safety and correctness of the serialization "bridge" between processes.

    This target specifically tests:

    • libmultiprocess event loop and connection handling.
    • Serialization/deserialization of core Bitcoin types (COutPoint, CScript) through Cap'n Proto Data fields.
    • Proxy/Server interaction using a reflected interface.

    The fuzz target uses an in-process two-way pipe to simulate a socket connection and implements a dummy IpcFuzzInterface to isolate the IPC logic from the rest of the node's state. It utilizes a static IpcFuzzSetup to minimize event loop overhead across fuzzing iterations.

    This PR also includes two preliminary commits that refactor fuzz target linking to use PRIVATE, aligning with project standards.

  2. DrahtBot added the label Fuzzing on Apr 20, 2026
  3. DrahtBot commented at 8:31 AM on April 20, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. enirox001 force-pushed on Apr 20, 2026
  5. DrahtBot added the label CI failed on Apr 20, 2026
  6. enirox001 force-pushed on Apr 20, 2026
  7. enirox001 force-pushed on Apr 20, 2026
  8. DrahtBot removed the label CI failed on Apr 20, 2026
  9. ViniciusCestarii commented at 6:37 PM on April 20, 2026: contributor

    While testing this PR with cmake --preset=libfuzzer, I noticed the new ipc target never makes it into the fuzz binary (FUZZ=ipc build_fuzz/bin/fuzz reports No fuzz target compiled for ipc).

    The cause is in the top-level CMakeLists.txt:234: when BUILD_FOR_FUZZING=ON, ENABLE_IPC is unconditionally forced OFF, which makes the if(ENABLE_IPC) guard in src/test/fuzz/CMakeLists.txt skip ipc.cpp. So the target added by this PR can't actually be exercised through the standard fuzz preset.

    I believe the fix is to drop set(ENABLE_IPC OFF) from CMakeLists.txt:234.

  10. ViniciusCestarii commented at 7:42 PM on April 20, 2026: contributor

    Three of the four methods (passOutPoint, passVectorUint8, passScript) are identity round-trips. add(a, b) is stronger because the server has to actually decode a and b to compute the sum and the client then checks against the original inputs.

    With identity, the server never has to understand the value it received, so a broken deserialization can be re-serialized as the same garbage and still compare equal. A small deterministic transform on the server side would close that gap, e.g.:

      std::vector<uint8_t> passVectorUint8(std::vector<uint8_t> v) {
          std::reverse(v.begin(), v.end());
          return v;
      }
      CScript passScript(CScript s) { s << OP_NOP; return s; }
      COutPoint passOutPoint(COutPoint o) { return COutPoint{o.hash, o.n ^ 0xFFFFFFFFu}; }
    

    and then comparing against the reproduced transform on the client just like add(a, b). This matches the "transform, reverse, or shift" idea from #23015.

  11. enirox001 force-pushed on Apr 21, 2026
  12. enirox001 force-pushed on Apr 21, 2026
  13. DrahtBot added the label CI failed on Apr 21, 2026
  14. DrahtBot commented at 3:58 AM on April 21, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task lint: https://github.com/bitcoin/bitcoin/actions/runs/24702970550/job/72250002067</sub> <sub>LLM reason (✨ experimental): CI failed due to a lint error for trailing whitespace detected by the trailing_whitespace check.</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  15. build: allow ipc when building for fuzzing
    Remove the unconditional disabling of IPC when building for fuzzing.
    This allows the compilation of fuzz targets that exercise the
    multiprocess infrastructure when IPC is enabled for the platform.
    04d4968327
  16. cmake: link fuzz targets privately
    Refactor the fuzz target linking to use the PRIVATE keyword in both
    the main fuzzing directory and the wallet-specific fuzzing directory.
    This ensures that all occurrences of target_link_libraries for the
    'fuzz' target use keyword signatures, preventing CMake configuration
    errors.
    
    This also aligns with project standards and prevents public dependency
    leakage.
    7560a524bc
  17. enirox001 force-pushed on Apr 21, 2026
  18. enirox001 force-pushed on Apr 21, 2026
  19. enirox001 commented at 4:43 AM on April 21, 2026: contributor

    Thanks for the review @ViniciusCestarii

    While testing this PR with cmake --preset=libfuzzer, I noticed the new ipc target never makes it into the fuzz binary (FUZZ=ipc build_fuzz/bin/fuzz reports No fuzz target compiled for ipc). I believe the fix is to drop set(ENABLE_IPC OFF) from CMakeLists.txt:234.

    The fix is indeed to remove set(ENABLE_IPC OFF) from the BUILD_FOR_FUZZING block, that line was added in af4156ab to work around missing capnp in fuzzing builds, but since add_libmultiprocess and add_subdirectory(ipc) are both gated behind ENABLE_IPC in src/CMakeLists.txt, users without capnp will still get ENABLE_IPC=OFF naturally with no configure error.

    With identity, the server never has to understand the value it received, so a broken deserialization can be re-serialized as the same garbage and still compare equal. A small deterministic transform on the server side would close that gap, e.g.:

      std::vector<uint8_t> passVectorUint8(std::vector<uint8_t> v) {
          std::reverse(v.begin(), v.end());
          return v;
      }
      CScript passScript(CScript s) { s << OP_NOP; return s; }
      COutPoint passOutPoint(COutPoint o) { return COutPoint{o.hash, o.n ^ 0xFFFFFFFFu}; }
    

    and then comparing against the reproduced transform on the client just like add(a, b). This matches the "transform, reverse, or shift" idea from #23015.

    Good point. Updated the three identity methods to use deterministic transforms instead:

    • passOutPoint: XORs n with 0xFFFFFFFF
    • passVectorUint8: reverses the vector
    • passScript: appends OP_NOP

    The client-side asserts now reproduce the same transform and compare against that

  20. enirox001 force-pushed on Apr 21, 2026
  21. enirox001 force-pushed on Apr 21, 2026
  22. enirox001 force-pushed on Apr 21, 2026
  23. fuzz: add ipc round-trip target
    Add a new fuzz target 'ipc' to test the multiprocess infrastructure.
    
    The target exercises the communication bridge between processes by
    using an in-process two-way pipe. It provides coverage for:
    - The libmultiprocess event loop and connection management.
    - Round-trip serialization of Bitcoin types (COutPoint, CScript)
      via the Cap'n Proto bridge.
    - Integrity of raw byte vectors (std::vector<uint8_t>).
    
    This serves as a foundation for fuzzing real node/wallet interfaces
    across the IPC boundary.
    c1fcd53b7d
  24. enirox001 force-pushed on Apr 21, 2026
  25. DrahtBot removed the label CI failed on Apr 21, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-21 09:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me