Skip to content

rust: add a fuzz target for the safe verifier path - #9297

Open
rodry957 wants to merge 2 commits into
google:masterfrom
rodry957:rust-fuzz-verifier-target
Open

rodry957 wants to merge 2 commits into
google:masterfrom
rodry957:rust-fuzz-verifier-target

Conversation

@rodry957

@rodry957 rodry957 commented Oct 2, 2026

Copy link
Copy Markdown

Summary

The Rust runtime (rust/flatbuffers) has no fuzz coverage. All eight fuzz targets live in tests/fuzzer/ and are C++ (verifier_fuzzer, scalar_fuzzer, parser_fuzzer, ...); there is no cargo-fuzz target anywhere in the tree. As a result the Rust safe reader path is not fuzzed even though it is the one that makes a promise: anything returned by flatbuffers::root::<T>() must be readable through the safe accessors without out-of-bounds accesses.

OSS-Fuzz policy is that fuzz targets belong in the project repository, and the OSS-Fuzz maintainer asked for exactly this in google/oss-fuzz#16202:

Please do this by Flatbuffers own repository, where the existing fuzzers are stored as well: https://github.com/google/flatbuffers

What this adds

A cargo-fuzz target, rust_verifier, that

  1. feeds arbitrary bytes to flatbuffers::root::<Monster>() and flatbuffers::size_prefixed_root::<Monster>() (the C++ verifier_fuzzer checks both root forms too);
  2. when verification succeeds, reads the result back exclusively through the safe (non-unsafe) API: the generated Monster accessors, the union accessors, and the public Table/VTable methods.

Any hole in the Rust verifier therefore shows up as a panic or an AddressSanitizer report instead of as silent memory corruption in a downstream user's program.

Layout

It is a standard cargo-fuzz project (the layout required by the OSS-Fuzz Rust guide):

rust/flatbuffers/fuzz/Cargo.toml
rust/flatbuffers/fuzz/fuzz_targets/rust_verifier.rs

It lives next to the crate it tests (rust/flatbuffers), which is where cargo fuzz init puts the fuzz/ directory, and it can be wired into OSS-Fuzz with:

cd $SRC/flatbuffers/rust/flatbuffers
cargo fuzz build -O
cp fuzz/target/x86_64-unknown-linux-gnu/release/rust_verifier $OUT/

The target reuses the schema-generated types that the Rust test-suite already checks in (tests/monster_test/mod.rs), i.e. exactly the code flatc emits for users, so no new schema or generated code is added.

Build and run

cd rust/flatbuffers
cargo +nightly fuzz build rust_verifier
cargo +nightly fuzz run rust_verifier fuzz/corpus/rust_verifier

A valid seed (e.g. tests/monsterdata_test.mon) runs clean.

Relation to the verifier fix

#9290 hardens exactly the paths this target exercises: it rejects degenerate vtables (vtable_len < 2 * SIZE_VOFFSET) in Verifier::visit_table, and makes the Rust generator verify union values whose discriminant is unknown instead of accepting them unchecked (_ => Ok(())). On the current master runtime this target already reproduces a crash: a buffer whose root table passes flatbuffers::root::<Monster>() while carrying an unknown union discriminant hands the reader an unverified union table, and the safe VTable API then reads past the end of the buffer. That is the class of bug the target is meant to catch, and it goes away once #9290 is in and the generated code is regenerated with the fixed generator.

cc @dbaileychess

All existing fuzz targets live in tests/fuzzer/ and are C++, so the Rust
runtime (rust/flatbuffers) had no fuzzing coverage at all. Its
flatbuffers::root::<T>() entry point promises that any buffer it accepts can
be read through the safe accessor API without out-of-bounds accesses, but
nothing was checking that promise.

Add a cargo-fuzz target next to the crate it tests. It feeds arbitrary bytes
to root::<T>() (plain and size-prefixed) and, whenever verification succeeds,
reads the result back exclusively through the safe API: the generated Monster
accessors, the union accessors and the public Table/VTable methods. A hole in
the verifier therefore surfaces as a panic or an AddressSanitizer report.

Requested for the project repository in google/oss-fuzz#16202.
@rodry957

Copy link
Copy Markdown
Author

This is the in-repo companion to #9290: a fuzz target that exercises the Rust verifier plus the public safe reader path (root::<T>() → table → vtable → inline size), so this class of bug gets coverage inside flatbuffers itself instead of only through the external OSS-Fuzz target.

Scope is deliberately narrow — 3 new files, +192/−0, no library changes: rust/flatbuffers/fuzz/Cargo.toml, rust/flatbuffers/fuzz/fuzz_targets/rust_verifier.rs and a .gitignore for the fuzz artifacts. CLA green, 7 checks green, mergeable: true.

It has never had a maintainer's opinion. If adding a fuzz/ crate to the repo is not something you want, say so and I will close it without argument — but if the concern is maintaining a target nobody asked for, note that the target in #9290's report already found the OOB read that #9298 fixes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant