Skip to content

Add fuzzers for OSS-Fuzz - #350

Open
Topogamer0 wants to merge 1 commit into
intel:mainfrom
Topogamer0:fuzzing
Open

Topogamer0 wants to merge 1 commit into
intel:mainfrom
Topogamer0:fuzzing

Conversation

@Topogamer0

Copy link
Copy Markdown

Add fuzzers for OSS-Fuzz

Following up on #346, this adds libFuzzer-compatible fuzzers in fuzz/ so TinyCBOR can be integrated into OSS-Fuzz.

What's included

  • parser_fuzzer: full traversal of every item (nested arrays, maps, tags), every getter, cross-checks between APIs; optional reader-API mode (incl. cbor_value_reparse()).
  • validate_fuzzer: cbor_value_validate() with flags taken from the input.
  • tojson_fuzzer: cbor_value_to_json_advance() with flags from the input; on glibc the output stream can fail after N bytes to exercise error paths.
  • pretty_fuzzer: cbor_value_to_pretty_advance_flags() and cbor_value_to_pretty_stream(), with a callback that can fail after N calls.
  • encoder_fuzzer: structured fuzzer; input bytes are encoder commands (arrays/maps, integers, strings, floats, tags, close). The output is compared between fixed-buffer, re-sized buffer and writer-function runs, then parsed back, validated and compared to what was encoded.
  • fuzz/corpus/: seeds from the CBOR data in the unit tests (minimized), fuzz/cbor.dict: dictionary of CBOR initial bytes.
  • BUILD_FUZZERS CMake option (default OFF); fuzz/README explains how to build and run.

Nothing in tools/ is fuzzed.

Assertions

As discussed, TinyCBOR's assertions check API usage, so the fuzzers are built without NDEBUG (they #error if it is defined) and an assertion failure is treated as a fuzzer bug. I first ran all fuzzers with assertions only (no sanitizers) and fixed the fuzzers until no assertion fired, then ran them with ASan+UBSan.

Testing

  • Assertions only (-fsanitize=fuzzer): ~20 minutes per fuzzer, no assertion failures.
  • ASan + UBSan, assertions on: 20 minutes per fuzzer (~100M executions in total), no findings.
  • Normal build with BUILD_FUZZERS OFF is unchanged.

These fuzzers were written with the help of Claude Code, and reviewed and tested by me.

The parser fuzzer also hits #347 (signed overflow in cbor_value_get_int()/cbor_value_get_int64()); until #349 is merged it avoids that case, and I'll tighten it afterwards.

While testing locally I also found 4 other possible low-severity issues in src/ (no memory corruption). How would you prefer them reported: public issues, or by email?

Add five fuzzers in fuzz/, built when the new BUILD_FUZZERS CMake option
is ON (default OFF, so the normal build is unchanged):

 - parser_fuzzer: decodes a sequence of items and visits every one of
   them, nested ones included, extracting every value and cross-checking
   the different APIs (copy vs dup vs chunked strings, checked vs
   unchecked integers, cbor_value_advance vs item-by-item traversal).
   Optionally uses the reader API, including cbor_value_reparse() with
   incrementally available data.
 - validate_fuzzer: cbor_value_validate() with any combination of flags.
 - tojson_fuzzer: cbor_value_to_json_advance() with any flags.
 - pretty_fuzzer: cbor_value_to_pretty_advance_flags() and
   cbor_value_to_pretty_stream() with any flags.
 - encoder_fuzzer: interprets the input as a sequence of encoder
   commands, runs it with a fixed-size buffer (and again with the size
   from cbor_encoder_get_extra_bytes_needed()) and with a writer
   function, then parses the result back, validates it and compares it
   to what was encoded.

The fuzzers must be built without NDEBUG, as the assertions check that
the API is used correctly. The seed corpus is the CBOR data from the
unit tests, minimized for coverage; cbor.dict lists the initial bytes
of the CBOR types.

The fuzzers were written with the help of Claude Code and reviewed and
tested by me.

Signed-off-by: Topogamer0 <topo.gamer.personal@gmail.com>

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant