Skip to content

Bug 5027 fuzz unification - #5121

Merged
graydon merged 4 commits into
stellar:masterfrom
graydon:bug-5027-fuzz-unification
May 2, 2026
Merged

Bug 5027 fuzz unification#5121
graydon merged 4 commits into
stellar:masterfrom
graydon:bug-5027-fuzz-unification

Conversation

@graydon

@graydon graydon commented Feb 3, 2026

Copy link
Copy Markdown
Contributor

Description

This is an initial step towards completion of #5027 -- it doesn't cover everything but it gets a lot of the basic reorganization done. I've ticked off the items in that bug that are done in this PR. There is a Soroban side of this change that now landed: stellar/rs-soroban-env#1646 though it's much less involved, just moves some code around.

To summarize the changes here:

  • All the old AFL-specific stuff is ripped out.
  • There's a new class FuzzTarget that you write a subclass of if you are writing a new fuzz target in C++.
    • This gives a clear, unambiguous "extension point" anytime someone wants to extend core's fuzzing (eg. write a fuzz target on contract or whatever).
    • If you're writing one on the Soroban side of Rust, the C++-side targets only vary by a single string name so they are not actually separate subclasses, just separate instances of the same class SorobanFuzzTarget, but the idea is the same. You add a target on the Rust side and you wire it into the dispatch function, by string name.
  • All existing fuzz targets, both Soroban and non, are registered in a single app-wide FuzzTargetRegistry.
    • The registry lets you list, run-once, and generate-a-corpus of a given size for the target.
  • Each target is also, separately, compilable in a way that fits the OSS-fuzz structure:
    • The Autoconf/Automake will, if configured with --enable-fuzz compile core with instrumentation and, separately, link one of 3 fuzz engines. You have to provide some separate env vars to specify the fuzz engine, which OSS-fuzz provides. It supports AFL++ (not old AFL), Libfuzzer, and Honggfuzz, and only supports each engine running in "persistent" mode (where the binary is observed by the fuzzer in-process).
    • The resulting instrumented and engine-linked artifacts get built "one executable per target", where you just run the executable to fuzz the target. So like the overlay fuzz target gets compiled into a binary called fuzz_overlay and so on.
  • Core and Soroban are updated to compile-in all the fuzz targets without instrumentation any time C++ BUILD_TESTS / Rust feature="testutils" is turned on, because...
    • Each target is also wired into the normal, runs-all-the-time unit test suite, with 2 tests per target:
      • A "smoke" unit test that just checks that the fuzz target still works and can produce at least a few successful runs.
      • A "regression" unit test that runs seeds saved in a regression suite.
  • Docs are updated to reflect all this.

Note: This change was written substantially by Opus 4.5 (on my direction from a fairly detailed spec) and it's made more than a few questionable choices during implementation (mostly over-complicating things). I am still in the process of reviewing, correcting, extending and minimizing its work.

Copilot AI review requested due to automatic review settings February 3, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a unified fuzzing infrastructure for stellar-core that replaces the old AFL-specific implementation. The changes enable fuzzing with multiple modern fuzz engines (libFuzzer, AFL++, honggfuzz) while integrating fuzz targets into the normal test suite for continuous regression testing.

Changes:

  • Introduces FuzzTarget interface and FuzzTargetRegistry for extensible fuzz target management
  • Migrates existing tx and overlay fuzz targets to the new framework
  • Adds Soroban fuzz target integration through Rust bridge
  • Updates build system to support modern fuzzer engines with proper instrumentation
  • Integrates fuzz targets as unit tests with corpus-based regression testing

Reviewed changes

Copilot reviewed 35 out of 38 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/util/Math.h Changes global state seed tracking to use optional to support fuzz initialization
src/util/Math.cpp Implements reinitializeAllGlobalStateForFuzzing for safe reseeding in fuzz contexts
src/test/test.cpp Updates to use optional API for seed retrieval
src/test/fuzz/targets/TxFuzzTarget.h New header defining transaction fuzzing target interface
src/test/fuzz/targets/TxFuzzTarget.cpp Implementation of transaction fuzzing with ledger setup
src/test/fuzz/targets/SorobanFuzzTargets.h Header for Soroban fuzz target wrappers
src/test/fuzz/targets/SorobanFuzzTargets.cpp C++ bridge to Rust-based Soroban fuzz targets
src/test/fuzz/targets/OverlayFuzzTarget.h Header for overlay/P2P message fuzzing
src/test/fuzz/targets/OverlayFuzzTarget.cpp Implementation of overlay network fuzzing
src/test/fuzz/FuzzUtils.h Shared utilities for compact XDR representation used in fuzzing
src/test/fuzz/FuzzUtils.cpp Implementation of fuzzing utilities and XDR compactor/unpacker
src/test/fuzz/FuzzTargetRegistry.h Central registry for fuzz target management
src/test/fuzz/FuzzTargetRegistry.cpp Implementation of fuzz target registry
src/test/fuzz/FuzzRegressionTests.cpp Shared test helpers for corpus regression and smoke tests
src/test/fuzz/FuzzMain.cpp LibFuzzer-compatible entry point for fuzz binaries
src/test/fuzz.h Removed old AFL-specific fuzzing interface
src/test/fuzz.cpp Removed old AFL-specific fuzzing implementation
src/test/FuzzerImpl.h Updated to remove old overlay fuzzer, keep tx fuzzer reference
src/test/FuzzerImpl.cpp Removed old fuzzer implementations (migrated to new structure)
src/simulation/ApplyLoad.h Changed constant to constexpr for consistency
src/rust/src/soroban_fuzz.rs New Rust module bridging to Soroban fuzz targets
src/rust/src/lib.rs Adds soroban_fuzz module to Rust library
src/rust/src/bridge.rs Adds FuzzResultCode enum and run_soroban_fuzz_target bridge function
src/rust/soroban/p25 Updates Soroban submodule to version with fuzz support
src/rust/Cargo.toml Adds fuzz and testutils features for fuzzing support
src/main/CommandLine.cpp Replaces old fuzz commands with new fuzz-one, gen-fuzz, and fuzz-list
src/Makefile.am Major build system changes to support modern fuzzing infrastructure
make-mks Excludes main.cpp and FuzzMain.cpp from shared source lists
docs/software/commands.md Updates command documentation for new fuzz commands
docs/fuzzing.md Completely rewrites fuzzing documentation for new infrastructure
configure.ac Replaces --enable-afl with --enable-fuzz supporting multiple engines
build-fuzz.sh New build script for oss-fuzz integration
Makefile.am Removes old AFL-specific targets
Builds/VisualStudio/stellar-core.vcxproj.filters Updates Visual Studio project filters for new file structure
Builds/VisualStudio/stellar-core.vcxproj Updates Visual Studio project for new fuzz files
.gitignore Adds fuzz_* binaries to gitignore

@socket-security

socket-security Bot commented Feb 3, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
License policy violation: cargo wasm-encoder

License: Apache-2.0 WITH LLVM-exception - The applicable license policy does not permit this license (5) (wasm-encoder-0.38.1/Cargo.toml)

License: Apache-2.0 WITH LLVM-exception - The applicable license policy does not permit this license (5) (wasm-encoder-0.38.1/LICENSE)

From: ?cargo/wasm-encoder@0.38.1

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore cargo/wasm-encoder@0.38.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: cargo wasm-smith

License: Apache-2.0 WITH LLVM-exception - The applicable license policy does not permit this license (5) (wasm-smith-0.13.1/Cargo.toml)

From: ?cargo/wasm-smith@0.13.1

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore cargo/wasm-smith@0.13.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@graydon
graydon marked this pull request as draft February 3, 2026 08:23
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch from 9f124d8 to e4b89e8 Compare February 4, 2026 07:13
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch 4 times, most recently from 4734932 to 80c0a52 Compare March 5, 2026 08:39
@graydon
graydon marked this pull request as ready for review March 5, 2026 08:41
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch from 80c0a52 to 263a4b9 Compare March 5, 2026 08:47
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch from 263a4b9 to 7d8fc98 Compare March 6, 2026 09:43
Comment thread src/Makefile.am Outdated
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch 2 times, most recently from dccf5da to 49ad594 Compare March 17, 2026 09:15
@graydon
graydon requested a review from sisuresh March 17, 2026 09:15
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch 6 times, most recently from 4b1c529 to da58b65 Compare May 1, 2026 05:21
@graydon
graydon force-pushed the bug-5027-fuzz-unification branch from da58b65 to 6c0863d Compare May 1, 2026 22:19

@anupsdf anupsdf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two suggestions from gpt 5.5 that seems reasonable. But we can also do this in a followup PR.

Comment thread src/rust/src/soroban_fuzz.rs Outdated
Comment thread Builds/VisualStudio/stellar-core.vcxproj Outdated
@anupsdf
anupsdf enabled auto-merge May 2, 2026 03:10
@anupsdf
anupsdf disabled auto-merge May 2, 2026 03:10
@graydon
graydon added this pull request to the merge queue May 2, 2026
Merged via the queue into stellar:master with commit 0cab98e May 2, 2026
53 checks passed
@graydon
graydon deleted the bug-5027-fuzz-unification branch May 2, 2026 05:55
pull Bot pushed a commit to mikeyhodl/stellar-core that referenced this pull request May 5, 2026
…lar#5250)

The recent change stellar#5121
broke the package builder by being a little too eager about anchoring a
regex in `make-mks` to the beginning of the line. Package builder does
its build from a tarball with NOGIT=1 and the prefix is different. Minor
fix.
pull Bot pushed a commit to DIGIIX-Ltd/stellar-core that referenced this pull request May 7, 2026
This rolls back one serious issue and fixes a few minor ones along the
way, all residual misunderstandings / bugs from previous iterations of
the final change that landed in
stellar#5121

- Main fix:
- Remove the `SOROBAN_MAX_PROTOCOL_TESTUTILS_FLAGS = --features =
testutils` setting from `src/Makefile.am` which turned on `testutils` in
the max protocol soroban host. This was here as a misunderstanding of
"which host actually gets fuzzed anyways": the `soroban-fuzz-targets`
dependency will actually bring in _its own_ `soroban-env-host` with
`testutils` enabled, and does not need anything changed on the
"production" hosts (the pNN ones compiled into .rlibs).
- Revert the change to `INVOKE_ADD_CACHED_COST_PASS` in
`InvokeHostFunctionTests.cpp` that I made in the previous PR to
compensate for this `testutils`-in-the-production-host change. This
should no longer be necessary, and rolling it back confirms that the
production hosts do not in fact have `testutils` enabled.
- Adjust comments to explain this a little better in
`src/rust/Cargo.toml`
- Smaller fixes:
  - Remove references to obsolete Makefile variable `CARGO_FEATURE_FUZZ`
- Fix an obsolete comment mentioning the obsolete `fuzz` feature in
`src/test/fuzz/FuzzRegressionTests.cpp`
- Remove overzealous `next`-guarding of `soroban-fuzz-targets` support
in the bridge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants