Skip to content

capnproto: add packed, JSON, text and schema-parser fuzz harnesses#57

Open
tc-agent wants to merge 2 commits into
masterfrom
capnproto-add-packed-and-json-harnesses
Open

capnproto: add packed, JSON, text and schema-parser fuzz harnesses#57
tc-agent wants to merge 2 commits into
masterfrom
capnproto-add-packed-and-json-harnesses

Conversation

@tc-agent

@tc-agent tc-agent commented May 10, 2026

Copy link
Copy Markdown
Owner

Motivation

capnproto currently ships a single fuzz harness (capnp-llvm-fuzzer-testcase) that exercises only the unpacked binary message reader. Per the Fuzz Introspector profile, reported line coverage sits at 6.51 % (2 451 / 37 649 lines). The packed-message decoder, JSON codec, text codec and schema-language compiler are unfuzzed.

Changes

Four new harnesses are added alongside the existing one. All take attacker-controlled bytes as input:

  • capnp-packed-fuzzer drives capnp::PackedMessageReader (the packed-encoding decoder in serialize-packed.c++).
  • capnp-json-fuzzer drives capnp::JsonCodec::decodeRaw (parser-only) and capnp::JsonCodec::decode against TestAllTypes (parser + schema-bound binding logic in compat/json.c++), then re-encodes to also exercise the encoder.
  • capnp-text-fuzzer drives capnp::TextCodec::decode against TestAllTypes, exercising serialize-text.c++ and the lexer it shares with the schema language.
  • capnp-schema-parser-fuzzer drives capnp::SchemaParser::parseFile via a tiny in-memory SchemaFile subclass (no kj filesystem allocation, avoiding a known cleanup-order leak), hitting the full schema-language pipeline: compiler/lexer.c++, compiler/parser.c++, compiler/node-translator.c++, compiler/compiler.c++, and schema-parser.c++.

build.sh is extended to compile the new harnesses against the .la-built libcapnp* / libcapnpc.a / libkj* archives produced by the existing make step. The Dockerfile COPYs the new sources and the (small) seeds/ directory.

Seed corpora

build.sh builds each seed corpus directly from the upstream tree at c++/src/capnp/testdata/ so no binary fixtures are vendored:

  • capnp-packed-fuzzer: packed, packedflat, segmented-packed — packed-encoded TestAllTypes messages produced upstream by capnp encode.
  • capnp-json-fuzzer: short.json, pretty.json, annotated.json.
  • capnp-text-fuzzer: short.txt, pretty.txt.
  • capnp-schema-parser-fuzzer: real upstream .capnp source files (c++.capnp, persistent.capnp, stream.capnp, compiler/grammar.capnp, compiler/lexer.capnp) plus one tiny hand-written schema (seeds/capnp-schema-parser-fuzzer/tiny.capnp, 14 lines, the only file under seeds/ in the diff) covering structs, unions, lists, enums and interfaces.

Coverage

Restricted to the set of files Fuzz Introspector measures, the new combined coverage is 8 862 / 38 344 = 23.11 % (vs the 6.51 % baseline, +16.6 pp). Linking libcapnpc.a adds the schema-compiler translation units to the instrumented denominator, so against the full new set of files coverage is 14 401 / 59 352 = 24.26 %.

Per-harness, after running all five harnesses concurrently for 5 minutes wall-clock each and producing an llvm-cov report from the resulting corpora:

harness lines covered %
capnp-llvm-fuzzer-testcase 3 574 / 37 649 9.49 %
capnp-packed-fuzzer (new) 1 985 / 9 254 21.45 %
capnp-json-fuzzer (new) 4 140 / 37 912 10.92 %
capnp-text-fuzzer (new) 5 730 / 45 802 12.51 %
capnp-schema-parser-fuzzer (new) 11 616 / 33 160 35.03 %
combined 14 402 / 59 368 24.26 %

Absolute lines covered grows from 2 45114 4025.9 × the Fuzz Introspector baseline.

@github-actions

github-actions Bot commented May 10, 2026

Copy link
Copy Markdown

Fuzzing Coverage Report

Tested: project capnproto · base 26deef8 → head 83bf809 · 300s total fuzz budget · updated 2026-05-27 19:03 UTC · workflow run

Metric Before After Delta
Static reachability >45m >45m
Line coverage 5.9% (2213/37653) 25.8% (14295/55514) +546.0%
Branch coverage 8.4% (613/7330) 32.0% (4099/12820) +568.7%
Function coverage 5.4% (507/9465) 19.4% (2358/12174) +365.1%

Per-harness

Harness Lines before Lines after Δ
capnp-json-fuzzer 0% 10.9% (4116/37916) new
capnp-llvm-fuzzer-testcase 5.9% (2213/37653) 5.6% (2106/37653) -4.8%
capnp-packed-fuzzer 0% 21.5% (1987/9258) new
capnp-schema-parser-fuzzer 0% 34.8% (11556/33164) new
capnp-text-fuzzer 0% 12.6% (5763/45806) new

Δ = (after − before) / before, to accommodate that denominators may change. "new" when before is 0; "deleted" when after is 0.

@tc-agent
tc-agent force-pushed the capnproto-add-packed-and-json-harnesses branch from aa5ede1 to 1d30fed Compare May 10, 2026 23:15
@tc-agent

Copy link
Copy Markdown
Owner Author

CI status: every per-engine project build (build (afl/centipede/libfuzzer/honggfuzz/none, …)) on capnproto passed. The single failing check is buildRun presubmit checks:

Missing license header in file /home/runner/work/oss-fuzz/oss-fuzz/.github/actions/fuzz-all/run_fuzzers.py.

run_fuzzers.py is part of the test-runner infrastructure injected into the PR by the review pipeline (visible in Changed files: alongside .github/actions/... entries) — it is not part of this projects/capnproto diff. The sister files in the same directory (render_comment.py, check_new_seeds.py) already carry the standard Apache 2.0 header for the same infra/presubmit.py check_license reason; this one was missed. Fix is trivial: add the same header to run_fuzzers.py.

@tc-agent
tc-agent force-pushed the master branch 15 times, most recently from 2c22875 to 07a0cf6 Compare May 14, 2026 09:29
@tc-agent
tc-agent force-pushed the capnproto-add-packed-and-json-harnesses branch from 1d30fed to 59e7321 Compare May 14, 2026 09:29
@tc-agent tc-agent changed the title capnproto: add packed-message and JSON fuzz harnesses capnproto: add packed, JSON, text and schema-parser fuzz harnesses May 14, 2026
@tc-agent
tc-agent force-pushed the master branch 7 times, most recently from d25286d to ed731ba Compare May 16, 2026 13:03
@tc-agent
tc-agent force-pushed the capnproto-add-packed-and-json-harnesses branch from 59e7321 to 5b4ec9f Compare May 16, 2026 13:03
@tc-agent
tc-agent force-pushed the master branch 3 times, most recently from c540264 to b54c0d2 Compare May 17, 2026 07:07
@tc-agent
tc-agent force-pushed the capnproto-add-packed-and-json-harnesses branch from d425517 to 68ef8ef Compare May 17, 2026 09:43
@tc-agent
tc-agent force-pushed the master branch 4 times, most recently from 9a36aa8 to 6a4a93d Compare May 21, 2026 13:42
@tc-agent
tc-agent force-pushed the master branch 3 times, most recently from 6125235 to e512e7e Compare May 27, 2026 06:33
@tc-agent
tc-agent force-pushed the capnproto-add-packed-and-json-harnesses branch from 68ef8ef to cad93a0 Compare May 27, 2026 07:53
@tc-agent
tc-agent force-pushed the master branch 5 times, most recently from b5fd10c to 712a52f Compare May 27, 2026 16:16
@tc-agent
tc-agent force-pushed the capnproto-add-packed-and-json-harnesses branch from cad93a0 to 83bf809 Compare May 27, 2026 16:45
@tc-agent
tc-agent force-pushed the master branch 2 times, most recently from a7587cd to b952f62 Compare May 28, 2026 02:55
@tc-agent tc-agent added the ready label May 28, 2026
@tc-agent
tc-agent force-pushed the master branch 4 times, most recently from af7f9a7 to 806b281 Compare May 28, 2026 18:05
@tc-agent tc-agent added forwarded and removed ready labels Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant