Fuzz tree deserialisation in CI - #84
Merged
Amaury Chamayou (achamayou) merged 4 commits intoAug 26, 2026
Merged
Conversation
Amaury Chamayou (achamayou)
force-pushed
the
achamayou-fuzz-tree-deserialisation
branch
from
August 24, 2026 14:59
b59937f to
8f42b49
Compare
Amaury Chamayou (achamayou)
force-pushed
the
achamayou-fuzz-tree-deserialisation
branch
from
August 24, 2026 20:48
8f42b49 to
6264df0
Compare
Amaury Chamayou (achamayou)
marked this pull request as ready for review
August 25, 2026 12:14
Copilot started reviewing on behalf of
Amaury Chamayou (achamayou)
August 25, 2026 12:14
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Adds opt-in libFuzzer coverage for tree deserialization and runs it in one sanitized Ubuntu CI configuration.
Changes:
- Adds a tree-deserialization fuzz harness and mutation dictionary.
- Configures Clang sanitizers and bounded CTest execution.
- Enables fuzzing for Ubuntu Debug with Clang and OpenSSL disabled.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
CMakeLists.txt |
Adds the FUZZING option. |
test/CMakeLists.txt |
Builds and registers the fuzz target. |
test/fuzz_tree_deserialise.cpp |
Implements the fuzz harness. |
test/tree_deserialise_fuzzer.dict |
Provides structured dictionary tokens. |
.github/workflows/ci.yml |
Enables fuzzing in the selected CI job. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Amaury Chamayou (achamayou)
force-pushed
the
achamayou-fuzz-tree-deserialisation
branch
2 times, most recently
from
August 25, 2026 12:57
9c4c8e0 to
9c2c337
Compare
Amaury Chamayou (achamayou)
changed the base branch from
achamayou-tree-size-validation
to
achamayou-tree-deserialise-ownership
August 25, 2026 12:59
Amaury Chamayou (achamayou)
force-pushed
the
achamayou-fuzz-tree-deserialisation
branch
from
August 25, 2026 15:09
9c2c337 to
b7cc117
Compare
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 73572868-1386-49b1-8849-ac9f9543ad3a
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Amaury Chamayou (achamayou)
force-pushed
the
achamayou-fuzz-tree-deserialisation
branch
from
August 25, 2026 15:45
b7cc117 to
860cd95
Compare
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
cjen1-msft
approved these changes
Aug 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FUZZINGCMake configuration for Clang/libFuzzermerkle::Tree::deserialiseclang+++ OpenSSL-OFF CI matrix entryTarget surface
LLVMFuzzerTestOneInputcopies the arbitrary input bytes into the representation accepted byTree::deserialise, starts at position zero, and deserialises into a fresh tree.std::runtime_errorandstd::out_of_rangeare treated as expected malformed-input rejections; sanitizer findings, process crashes, and unexpected exception types fail the target.Because this PR is based directly on
achamayou-tree-size-validation, the harness exercises the combined bounds, ownership/exception-safety, and representability checks from the lower stack layers.Structured input generation and corpus
The libFuzzer dictionary contains five structured byte sequences:
These tokens steer mutation toward serialized count and hash fields. There is no checked-in persistent corpus: each bounded run starts from libFuzzer's empty corpus, uses the dictionary to generate structured inputs, and builds an ephemeral in-memory corpus for that run.
Sanitizers
The fuzz executable is compiled and linked with:
This combines libFuzzer with AddressSanitizer and UndefinedBehaviorSanitizer. Linux ASan supplies LeakSanitizer support; the local validation below explicitly enabled
detect_leaks=1and configured both sanitizers to halt on the first finding.Bounded CI configuration
FUZZINGis enabled only for the Ubuntu Debug,clang++, OpenSSL-OFF matrix job. CTest invokes the target with:This gives a deterministic mutation seed, exactly 200,000 executions, a 4 KiB input cap, a five-second per-input timeout, and a 60-second CTest test timeout. The surrounding CI CTest invocation also has a 300-second timeout.
Failure artifacts and reproduction
On a crash or sanitizer finding, libFuzzer prints the failing input and writes its usual artifact (for example,
crash-*,leak-*, ortimeout-*) in the test working directory,build/<configuration>/test. The current workflow preserves the diagnostic in the verbose CTest log but does not upload the artifact separately.After downloading or reconstructing the reported artifact, reproduce it with the same sanitized binary:
For a bounded replay with the PR's dictionary and deterministic seed, rerun the CTest command below.
Local validation
Validated on Ubuntu 26.04 under WSL, Clang 21.1.8, and CMake 4.2.3 with the CI-failing Clang-tidy configuration enabled:
The fuzz target built cleanly under Clang-tidy and completed all 200,000 fixed-seed executions in 13.60 seconds (
cov: 456,ft: 1628, ephemeral corpus55/7726b, peak RSS 201 MB) with no ASan, UBSan, or leak finding.unit_testspassed all 12 test cases and 187 assertions under the same sanitizer and Clang-tidy build.Stack
Depends on #82, which is stacked on #80 and #78.