feat(fuzz): add libFuzzer-based fuzzing infrastructure#5314
Open
lgritz wants to merge 1 commit into
Open
Conversation
Add continuous fuzz testing for OpenImageIO's image format readers, so malformed/adversarial inputs get caught by CI instead of by users. - src/fuzz/: a single dynamic-dispatch harness, oiio_fuzz_image, covers all format plugins by discovering formats at runtime and targeting one per process (env var, argv[0], or --format=). New format plugins get fuzz coverage automatically -- no harness to write, just a seed corpus directory, enforced by a CI lint job. - The per-input read loop (chunked scanline/tile reads, subimage/MIP iteration, OOM-bounded) lives in the library itself as OIIO::pvt::test_read_image()/test_read_all_images(), shared with a new `oiiotool --testread` debugging flag. This `oiiotool --testread` command is useful in its own right for testing whether a file can be fully read without needing the pixels stored. - .github/workflows/fuzz.yml runs a 29-format parallel matrix nightly (and on pushes to "fuzz"-named branches), tiered by risk: 1hr/job for the 10 most important formats, 30min for the rest, with per-format corpus caching across runs and crash-artifact upload. - Seed corpora: a handful of formats with no other source commit a synthetic seed; everything else is pulled from testsuite/ and companion image repos (including oiio-images) at fuzz time rather than committed wholesale. So the fuzzing seeds will also grow as we check in more test cases. - Gated behind OIIO_BUILD_FUZZ_TARGETS=OFF; requires upstream clang (gcc and Apple's clang are skipped with a warning, not a hard build failure). - docs/dev/fuzzing.md covers the local build/run/reproduce/minimize workflow, and docs/dev/specs/001-image-fuzzing archives all the spec-kit design history and rationale. OSS-Fuzz onboarding (project.yaml/Dockerfile/build.sh) is scoped but not yet built -- the harness's format-dispatch and $LIB_FUZZING_ENGINE linkage are already in place for whenever that's picked up. Assisted-by: Claude Code / Claude Sonnet 5 Signed-off-by: Larry Gritz <lg@larrygritz.com>
Collaborator
Author
|
BTW, the reason some fuzz tests are failing is that there are still several PRs still in flight (and a couple fixes for which I haven't yet submitted PRs at all) that fix things being spotted by the fuzzing. When I do a test push of the fuzzing mechanism AND all the fixes I've implemented to far, it tends to pass. So the tests will gradually all go green as we continue to merge fixes. |
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.
Add continuous fuzz testing for OpenImageIO's image format readers, so malformed/adversarial inputs get caught by CI instead of by users.
src/fuzz/: a single dynamic-dispatch harness, oiio_fuzz_image, covers all format plugins by discovering formats at runtime and targeting one per process (env var, argv[0], or --format=). New format plugins get fuzz coverage automatically -- no harness to write, just a seed corpus directory, enforced by a CI lint job.
The per-input read loop (chunked scanline/tile reads, subimage/MIP iteration, OOM-bounded) lives in the library itself as OIIO::pvt::test_read_image()/test_read_all_images(), shared with a new
oiiotool --testreaddebugging flag. Thisoiiotool --testreadcommand is useful in its own right for testing whether a file can be fully read without needing the pixels stored..github/workflows/fuzz.yml runs a 29-format parallel matrix nightly (and on pushes to "fuzz"-named branches), tiered by risk: 1hr/job for the 10 most important formats, 30min for the rest, with per-format corpus caching across runs and crash-artifact upload.
Seed corpora: a handful of formats with no other source commit a synthetic seed; everything else is pulled from testsuite/ and companion image repos (including oiio-images) at fuzz time rather than committed wholesale. So the fuzzing seeds will also grow as we check in more test cases.
Gated behind OIIO_BUILD_FUZZ_TARGETS=OFF; requires upstream clang (gcc and Apple's clang are skipped with a warning, not a hard build failure).
docs/dev/fuzzing.md covers the local build/run/reproduce/minimize workflow, and docs/dev/specs/001-image-fuzzing archives all the spec-kit design history and rationale.
OSS-Fuzz onboarding (project.yaml/Dockerfile/build.sh) is scoped but not yet built -- the harness's format-dispatch and $LIB_FUZZING_ENGINE linkage are already in place for whenever that's picked up.
Assisted-by: Claude Code / Claude Sonnet 5