Skip to content

[Tracking]: retain encrypted private fuzz evidence for candidate diagnosis #46

Closed

Description

@YUZHEthefool

Problem

The scheduled fuzz workflow intentionally publishes only an opaque HMAC candidate ID. Raw libFuzzer inputs, stack traces and QEMU evidence were kept only in RUNNER_TEMP and discarded when the job ended. As a result, the two open candidates (#40 and #41) cannot be reproduced or root-caused from the run artifacts, even by maintainers.

Outcome

Retain failure-only plaintext evidence inside the runner, seal it with age, and publish only ciphertext. The public candidate schema and issue format stay unchanged.

Scope

  • Add scripts/fuzz/private_evidence.py to run a campaign, record revision/hashes/tool versions/command/exit status and the raw libFuzzer log, then stream a tar/gzip archive into age.
  • Add failure-only QEMU evidence retention: submitted program, guest image, disk, serial log, QEMU stderr and an outcome.json receipt distinguishing crash, boot_timeout, guest_hang and execution_error.
  • Add crash-triage --private-index so public candidate IDs map to retained inputs in a private file; the public report remains exactly two fields.
  • Upload only fuzz-evidence-<job-index>/campaign.tar.gz.age (90-day retention). Plaintext never enters a cache or artifact.
  • Make the campaign fail closed when FUZZ_EVIDENCE_RECIPIENTS is missing or malformed, or when encryption/upload fails, so no public candidate pointer is created without evidence.
  • Set the QEMU libFuzzer per-input timeout to 1200 seconds in the runner and local Makefile campaign targets, above the executor's 900-second guest bound.
  • Document the maintainer workflow (age-keygen, repository variable, decryption) and the fact that candidate IDs deduplicate inputs, not root causes.

Validation

  • scripts/tests Python suite: 198 passed (9 new evidence tests, including real age round-trip, tamper rejection, symlink/hardlink refusal, size limits and non-zero campaign exit handling).
  • scripts/ci/entrypoint.sh tools: all four gates pass; make lint passes.
  • userspace/fuzzer: 15 unit + 1 smoke + 7 executor + 4 scaffold tests pass; Clippy -D warnings passes; release crash-triage build passes.
  • userspace/nilix-syz-fuzzer: 34 tests pass.
  • fuzz qemu-executor tests: 5 pass, including failure receipt and artifact retention.
  • Repository variable FUZZ_EVIDENCE_RECIPIENTS preflight already succeeds with the installed age.

Limitations

Related candidates: #40, #41.

Activity

  1. added
    enhancementNew feature or request
    area: fuzzingFuzz targets, corpora, executors, triage, and KCOV workflows
    area: tooling/CIBuild system, scripts, hooks, automation, and repository tooling
    securitySecurity-sensitive hardening or privately coordinated remediation
    on Oct 30, 2026
  2. added
    needs: triageNeeds maintainer classification, verification, and priority
    trackingTracks an accepted multi-step project or release-gate item
    on Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: fuzzingFuzz targets, corpora, executors, triage, and KCOV workflowsarea: tooling/CIBuild system, scripts, hooks, automation, and repository toolingenhancementNew feature or requestneeds: triageNeeds maintainer classification, verification, and prioritysecuritySecurity-sensitive hardening or privately coordinated remediationtrackingTracks an accepted multi-step project or release-gate item

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions