Repository navigation
ci(fuzz): keep failing inputs out of public logs and artifacts - #864
Open
LeeroyHannigan wants to merge 4 commits into
Open
LeeroyHannigan wants to merge 4 commits into
LeeroyHannigan wants to merge 4 commits into
Conversation
A fork inherits the daily schedule but not the ExtendDB runner group, so in a fork that enables Actions the schedule queues six jobs for a runner label that the fork does not have. The job now runs only when the repository owner is ExtendDB. The runner group belongs to the organization, so the check reads the repository owner. A pull request from a fork still runs, because its workflow runs in the base repository. The root .cargo/config.toml sets the resolver that cargo metadata uses when the workflow builds fuzz/Cargo.lock, so the pull_request paths now include .cargo/.
The log and the artifacts of a workflow run in a public repository are public. When an input crashed, timed out or ran out of memory, the workflow uploaded it as an artifact, libFuzzer printed it in the log as bytes and as base64 when it was 256 bytes or less, and cargo-fuzz printed it in full. libFuzzer also wrote an input that ran for more than 10 seconds, and printed it under the same size limit, on a run that passed. The SigV4 targets parse a request before the caller is authenticated, so such an input can be a denial of service that SECURITY.md asks to be reported privately. The Fuzz step now writes the cargo-fuzz and libFuzzer output to a file under $RUNNER_TEMP and prints only the final statistics of a clean run. It fails with a fixed message when libFuzzer exits with an error or leaves any file under fuzz/artifacts, so a slow input fails the job too. The upload step is removed. A new Build step runs cargo fuzz build before the Fuzz step, so build errors stay in the log. Tests: a local run of the step script printed only the statistics for a clean run. With an out-of-memory failure it printed only the error line, and the lines that print the input stayed in the log file.
validate_timestamp reads one header, x-amz-date. The target built up to three arbitrary headers before it, so part of each input went to header names and values that validate_timestamp does not read. The whole input is now the x-amz-date value. build_header_map, which only this target used, is removed. The two seeds lose the leading byte that set the header count to zero. Tests: a local 30-second run from the seeds made 4.7 million executions and found no failing input.
Most mutations of the three policy seeds break the JSON, and no seed has a Principal, NotPrincipal or Sid key. In four local 60-second runs from those seeds, no input in the final corpus had a statement with one of those keys, so the runs did not reach parse_principal_value or the Sid check in from_json_for_write. fuzz/dicts/policy_document.dict lists the policy keys, the Effect and Version values, the condition operators with their ForAllValues:, ForAnyValue: and IfExists forms, and CIDR forms. The Fuzz step passes the dictionary of a target with -dict when fuzz/dicts has one. One new seed has a Principal object, NotResource, a valid Sid, and ForAllValues and IfExists conditions. The other is a single statement object with NotPrincipal, NotAction, a Sid that the write path refuses, and the other operator families. Tests: the two seeds raise the start coverage that libFuzzer reports from 397 to 532. In four local 60-second runs with the seeds and the dictionary, each final corpus had 63 to 117 statements with a Principal or NotPrincipal key and 92 to 122 with a Sid. The final coverage was 1472 to 1675, against 1341 to 1595 from the old seeds.
LeeroyHannigan
requested review from
amrith,
c33howard,
eliseong,
hitesh96db,
jcshepherd,
navareamol,
pdf-amzn and
robinnsc
as code owners
November 5, 2026 16:32
This branch has not been deployed
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.
What
fuzz/artifacts, the step fails with a fixed message. The change removes the upload step. A new Build step keeps build errors in the log..cargo/**is in thepull_requestpaths.sigv4_timestampgets only thex-amz-datevalue. The change removesbuild_header_map.policy_documentgets a dictionary infuzz/dicts/and two seeds. The Fuzz step passes the dictionary of a target with-dict.The workflow does not add
-a. cargo-fuzz 0.13.2 builds with-Cdebug-assertionsunless the command passes-O, so overflow checks anddebug_assert!are already on.Why
@robinnsc raised these points on #798.
.cargo/config.tomlapplies when the workflow buildsfuzz/Cargo.lock.validate_timestampreads onlyx-amz-date, so the extra headers used part of each input on bytes that it does not read.Refs #798
Testing done
actionlintwith shellcheck passes on the workflow, with the runner label declared.Doneandstat::lines.-rss_limit_mb=1, the run failed with an out-of-memory input. The step printed only the error line, and the lines that print the input stayed in the log file.fuzz/artifactsafter a clean run, the step failed with the error line.cargo fuzz build -von nightly-2026-11-01 passed-Cdebug-assertionsand-Zsanitizer=addressto every target crate.sigv4_timestamp: a 30-second run from the seeds made 4.7 million executions and found no failing input.policy_document, four local 60-second runs for each setup:fuzz/Cargo.lockstep and its version check pass.cargo +1.97.0 fmt --checkandcargo +1.97.0 clippy --all-targets -- -D warningspass infuzz/.Checklist
cargo test --workspace)cargo fmt --check)cargo clippy -- -W clippy::pedantic)Storagetrait, auth model, on-diskformat, or public CLI surface, an RFC has been accepted or is linked
below. Otherwise, an ADR captures the decision (link below).
The change touches only
fuzz/and the Fuzz workflow, so the workspace tests do not cover it. Clippy ran with-D warningsinfuzz/, without the pedantic group.ADR / RFC: n/a
Not in this pull request
Separate issues track these points from the #798 comments:
expression_evaluatetoward the condition and update evaluators.sigv4_verifyfixed header names with fuzzed values.By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.